From aee84333e2d7b8a9958501d998099ce1793ac68c Mon Sep 17 00:00:00 2001 From: Andrii Grynenko Date: Tue, 9 Aug 2016 19:53:52 -0700 Subject: [PATCH] Use ReadMostlyMainPtrDeleter in folly::Singleton Reviewed By: yfeldblum Differential Revision: D3691541 fbshipit-source-id: 9488c1487ebd0500a23300292215456ca3220f03 --- folly/Singleton-inl.h | 8 ++++++++ folly/Singleton.cpp | 8 ++++++++ folly/Singleton.h | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/folly/Singleton-inl.h b/folly/Singleton-inl.h index 386b40bd..a326b12b 100644 --- a/folly/Singleton-inl.h +++ b/folly/Singleton-inl.h @@ -140,10 +140,18 @@ bool SingletonHolder::hasLiveInstance() { return !instance_weak_.expired(); } +template +void SingletonHolder::preDestroyInstance( + ReadMostlyMainPtrDeleter<>& deleter) { + instance_copy_ = instance_; + deleter.add(std::move(instance_)); +} + template void SingletonHolder::destroyInstance() { state_ = SingletonHolderState::Dead; instance_.reset(); + instance_copy_.reset(); if (destroy_baton_) { constexpr std::chrono::seconds kDestroyWaitTime{5}; auto wait_result = destroy_baton_->timed_wait( diff --git a/folly/Singleton.cpp b/folly/Singleton.cpp index df3cbcb0..c1031944 100644 --- a/folly/Singleton.cpp +++ b/folly/Singleton.cpp @@ -193,6 +193,14 @@ void SingletonVault::destroyInstances() { CHECK_GE(singletons_.size(), creation_order_.size()); + // Release all ReadMostlyMainPtrs at once + { + ReadMostlyMainPtrDeleter<> deleter; + for (auto& singleton_type : creation_order_) { + singletons_[singleton_type]->preDestroyInstance(deleter); + } + } + for (auto type_iter = creation_order_.rbegin(); type_iter != creation_order_.rend(); ++type_iter) { diff --git a/folly/Singleton.h b/folly/Singleton.h index 89bc28be..297cb8b9 100644 --- a/folly/Singleton.h +++ b/folly/Singleton.h @@ -227,6 +227,7 @@ class SingletonHolderBase { virtual bool hasLiveInstance() = 0; virtual void createInstance() = 0; virtual bool creationStarted() = 0; + virtual void preDestroyInstance(ReadMostlyMainPtrDeleter<>&) = 0; virtual void destroyInstance() = 0; private: @@ -255,6 +256,7 @@ struct SingletonHolder : public SingletonHolderBase { virtual bool hasLiveInstance() override; virtual void createInstance() override; virtual bool creationStarted() override; + virtual void preDestroyInstance(ReadMostlyMainPtrDeleter<>&) override; virtual void destroyInstance() override; private: @@ -283,6 +285,8 @@ struct SingletonHolder : public SingletonHolderBase { // holds a ReadMostlyMainPtr to singleton instance, set when state is changed // from Dead to Living. Reset when state is changed from Living to Dead. folly::ReadMostlyMainPtr instance_; + // used to release all ReadMostlyMainPtrs at once + folly::ReadMostlySharedPtr instance_copy_; // weak_ptr to the singleton instance, set when state is changed from Dead // to Living. We never write to this object after initialization, so it is // safe to read it from different threads w/o synchronization if we know -- 2.34.1