BatchDispatcher exception handling
[folly.git] / folly / Singleton.h
index e083e35b6d5dae5ed6c908d576d6999a018514a7..0539e28055e294a05bbd18d167a69cbe071e5dc3 100644 (file)
 #include <folly/Demangle.h>
 #include <folly/Executor.h>
 #include <folly/experimental/ReadMostlySharedPtr.h>
+#include <folly/detail/StaticSingletonManager.h>
 
 #include <algorithm>
 #include <atomic>
@@ -160,47 +161,6 @@ class SingletonVault;
 
 namespace detail {
 
-// This internal-use-only class is used to create all leaked Meyers singletons.
-// It guarantees that only one instance of every such singleton will ever be
-// created, even when requested from different compilation units linked
-// dynamically.
-class StaticSingletonManager {
- public:
-  static StaticSingletonManager& instance();
-
-  template <typename T, typename Tag, typename F>
-  inline T* create(F&& creator) {
-    std::lock_guard<std::mutex> lg(mutex_);
-
-    auto& id = typeid(TypePair<T, Tag>);
-    auto& ptr = reinterpret_cast<T*&>(map_[id]);
-    if (!ptr) {
-      ptr = creator();
-    }
-    return ptr;
-  }
-
- private:
-  template <typename A, typename B>
-  class TypePair {};
-
-  StaticSingletonManager() {}
-
-  std::unordered_map<std::type_index, intptr_t> map_;
-  std::mutex mutex_;
-};
-
-template <typename T, typename Tag, typename F>
-inline T* createGlobal(F&& creator) {
-  return StaticSingletonManager::instance().create<T, Tag>(
-      std::forward<F>(creator));
-}
-
-template <typename T, typename Tag>
-inline T* createGlobal() {
-  return createGlobal<T, Tag>([]() { return new T(); });
-}
-
 struct DefaultTag {};
 
 // A TypeDescriptor is the unique handle for a given singleton.  It is
@@ -258,16 +218,20 @@ class TypeDescriptorHasher {
 // SingletonHolders.
 class SingletonHolderBase {
  public:
+  explicit SingletonHolderBase(TypeDescriptor typeDesc) : type_(typeDesc) {}
   virtual ~SingletonHolderBase() = default;
 
-  virtual TypeDescriptor type() = 0;
+  TypeDescriptor type() const {
+    return type_;
+  }
   virtual bool hasLiveInstance() = 0;
   virtual void createInstance() = 0;
   virtual bool creationStarted() = 0;
+  virtual void preDestroyInstance(ReadMostlyMainPtrDeleter<>&) = 0;
   virtual void destroyInstance() = 0;
 
- protected:
-  static constexpr std::chrono::seconds kDestroyWaitTime{5};
+ private:
+  TypeDescriptor type_;
 };
 
 // An actual instance of a singleton, tracking the instance itself,
@@ -289,10 +253,10 @@ struct SingletonHolder : public SingletonHolderBase {
 
   void registerSingleton(CreateFunc c, TeardownFunc t);
   void registerSingletonMock(CreateFunc c, TeardownFunc t);
-  virtual TypeDescriptor type() override;
   virtual bool hasLiveInstance() override;
   virtual void createInstance() override;
   virtual bool creationStarted() override;
+  virtual void preDestroyInstance(ReadMostlyMainPtrDeleter<>&) override;
   virtual void destroyInstance() override;
 
  private:
@@ -304,7 +268,6 @@ struct SingletonHolder : public SingletonHolderBase {
     Living,
   };
 
-  TypeDescriptor type_;
   SingletonVault& vault_;
 
   // mutex protects the entire entry during construction/destruction
@@ -322,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
@@ -483,6 +448,10 @@ class SingletonVault {
     return *stackTraceGetterPtr;
   }
 
+  void setType(Type type) {
+    type_ = type;
+  }
+
  private:
   template <typename T>
   friend struct detail::SingletonHolder;