Use ReadMostlyMainPtrDeleter in folly::Singleton
authorAndrii Grynenko <andrii@fb.com>
Wed, 10 Aug 2016 02:53:52 +0000 (19:53 -0700)
committerFacebook Github Bot 6 <facebook-github-bot-6-bot@fb.com>
Wed, 10 Aug 2016 03:08:42 +0000 (20:08 -0700)
Reviewed By: yfeldblum

Differential Revision: D3691541

fbshipit-source-id: 9488c1487ebd0500a23300292215456ca3220f03

folly/Singleton-inl.h
folly/Singleton.cpp
folly/Singleton.h

index 386b40bd96839fb1eb045c20fb8b4b15c93a42f6..a326b12b1a920baac505d8c690ddd933d8d0eb55 100644 (file)
@@ -140,10 +140,18 @@ bool SingletonHolder<T>::hasLiveInstance() {
   return !instance_weak_.expired();
 }
 
+template <typename T>
+void SingletonHolder<T>::preDestroyInstance(
+    ReadMostlyMainPtrDeleter<>& deleter) {
+  instance_copy_ = instance_;
+  deleter.add(std::move(instance_));
+}
+
 template <typename T>
 void SingletonHolder<T>::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(
index df3cbcb059cdd647061402474bf18e3b81d90651..c1031944313c610dfbfc33e97062119295e89c40 100644 (file)
@@ -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) {
index 89bc28be9d87645831ba5a2b5c454613dbadf6fc..297cb8b938b4070ef129d449feaf9712c5e5b559 100644 (file)
@@ -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<T> instance_;
+  // used to release all ReadMostlyMainPtrs at once
+  folly::ReadMostlySharedPtr<T> 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