Singleton: un-inline initialization-time-only methods
authorSteve O'Brien <steveo@fb.com>
Wed, 7 Oct 2015 13:23:01 +0000 (06:23 -0700)
committerfacebook-github-bot-4 <folly-bot@fb.com>
Wed, 7 Oct 2015 14:20:15 +0000 (07:20 -0700)
Summary: Move some methods which are generally only used during initialization time (registration, eager-init functions) from the header to the .cpp file

Reviewed By: @luciang

Differential Revision: D2513043

fb-gh-sync-id: 58d1f6e0d158d805a12b8d267421927b3cfc6118

folly/Singleton.cpp
folly/Singleton.h

index 1029097146aa295c0b6633ebcfd5ac328eb8bfc0..5e4e88beebbc5792e2fe72501d336c911f0928c2 100644 (file)
@@ -56,6 +56,101 @@ FatalHelper __attribute__ ((__init_priority__ (101))) fatalHelper;
 
 SingletonVault::~SingletonVault() { destroyInstances(); }
 
+void SingletonVault::registerSingleton(detail::SingletonHolderBase* entry) {
+  RWSpinLock::ReadHolder rh(&stateMutex_);
+
+  stateCheck(SingletonVaultState::Running);
+
+  if (UNLIKELY(registrationComplete_)) {
+    throw std::logic_error(
+      "Registering singleton after registrationComplete().");
+  }
+
+  RWSpinLock::ReadHolder rhMutex(&mutex_);
+  CHECK_THROW(singletons_.find(entry->type()) == singletons_.end(),
+              std::logic_error);
+
+  RWSpinLock::UpgradedHolder wh(&mutex_);
+  singletons_[entry->type()] = entry;
+}
+
+void SingletonVault::addEagerInitSingleton(detail::SingletonHolderBase* entry) {
+  RWSpinLock::ReadHolder rh(&stateMutex_);
+
+  stateCheck(SingletonVaultState::Running);
+
+  if (UNLIKELY(registrationComplete_)) {
+    throw std::logic_error(
+        "Registering for eager-load after registrationComplete().");
+  }
+
+  RWSpinLock::ReadHolder rhMutex(&mutex_);
+  CHECK_THROW(singletons_.find(entry->type()) != singletons_.end(),
+              std::logic_error);
+
+  RWSpinLock::UpgradedHolder wh(&mutex_);
+  eagerInitSingletons_.insert(entry);
+}
+
+void SingletonVault::registrationComplete() {
+  RequestContext::saveContext();
+  std::atexit([](){ SingletonVault::singleton()->destroyInstances(); });
+
+  RWSpinLock::WriteHolder wh(&stateMutex_);
+
+  stateCheck(SingletonVaultState::Running);
+
+  if (type_ == Type::Strict) {
+    for (const auto& p : singletons_) {
+      if (p.second->hasLiveInstance()) {
+        throw std::runtime_error(
+            "Singleton created before registration was complete.");
+      }
+    }
+  }
+
+  registrationComplete_ = true;
+}
+
+void SingletonVault::doEagerInit() {
+  std::unordered_set<detail::SingletonHolderBase*> singletonSet;
+  {
+    RWSpinLock::ReadHolder rh(&stateMutex_);
+    stateCheck(SingletonVaultState::Running);
+    if (UNLIKELY(!registrationComplete_)) {
+      throw std::logic_error("registrationComplete() not yet called");
+    }
+    singletonSet = eagerInitSingletons_; // copy set of pointers
+  }
+
+  for (auto *single : singletonSet) {
+    single->createInstance();
+  }
+}
+
+Future<Unit> SingletonVault::doEagerInitVia(Executor* exe) {
+  std::unordered_set<detail::SingletonHolderBase*> singletonSet;
+  {
+    RWSpinLock::ReadHolder rh(&stateMutex_);
+    stateCheck(SingletonVaultState::Running);
+    if (UNLIKELY(!registrationComplete_)) {
+      throw std::logic_error("registrationComplete() not yet called");
+    }
+    singletonSet = eagerInitSingletons_; // copy set of pointers
+  }
+
+  std::vector<Future<Unit>> resultFutures;
+  for (auto* single : singletonSet) {
+    resultFutures.emplace_back(via(exe).then([single] {
+      if (!single->creationStarted()) {
+        single->createInstance();
+      }
+    }));
+  }
+
+  return collectAll(resultFutures).via(exe).then();
+}
+
 void SingletonVault::destroyInstances() {
   RWSpinLock::WriteHolder state_wh(&stateMutex_);
 
index f3569594741d91f2633dd11afe10aca1cf6cba11..ffccd675a3d17f5c9d36cd7653eeab1e94c37749 100644 (file)
@@ -318,68 +318,18 @@ class SingletonVault {
   // registration is not complete. If validations succeeds,
   // register a singleton of a given type with the create and teardown
   // functions.
-  void registerSingleton(detail::SingletonHolderBase* entry) {
-    RWSpinLock::ReadHolder rh(&stateMutex_);
-
-    stateCheck(SingletonVaultState::Running);
-
-    if (UNLIKELY(registrationComplete_)) {
-      throw std::logic_error(
-        "Registering singleton after registrationComplete().");
-    }
-
-    RWSpinLock::ReadHolder rhMutex(&mutex_);
-    CHECK_THROW(singletons_.find(entry->type()) == singletons_.end(),
-                std::logic_error);
-
-    RWSpinLock::UpgradedHolder wh(&mutex_);
-    singletons_[entry->type()] = entry;
-  }
+  void registerSingleton(detail::SingletonHolderBase* entry);
 
   /**
    * Called by `Singleton<T>.shouldEagerInit()` to ensure the instance
    * is built when `doEagerInit[Via]` is called; see those methods
    * for more info.
    */
-  void addEagerInitSingleton(detail::SingletonHolderBase* entry) {
-    RWSpinLock::ReadHolder rh(&stateMutex_);
-
-    stateCheck(SingletonVaultState::Running);
-
-    if (UNLIKELY(registrationComplete_)) {
-      throw std::logic_error(
-          "Registering for eager-load after registrationComplete().");
-    }
-
-    RWSpinLock::ReadHolder rhMutex(&mutex_);
-    CHECK_THROW(singletons_.find(entry->type()) != singletons_.end(),
-                std::logic_error);
-
-    RWSpinLock::UpgradedHolder wh(&mutex_);
-    eagerInitSingletons_.insert(entry);
-  }
+  void addEagerInitSingleton(detail::SingletonHolderBase* entry);
 
   // Mark registration is complete; no more singletons can be
   // registered at this point.
-  void registrationComplete() {
-    RequestContext::saveContext();
-    std::atexit([](){ SingletonVault::singleton()->destroyInstances(); });
-
-    RWSpinLock::WriteHolder wh(&stateMutex_);
-
-    stateCheck(SingletonVaultState::Running);
-
-    if (type_ == Type::Strict) {
-      for (const auto& p : singletons_) {
-        if (p.second->hasLiveInstance()) {
-          throw std::runtime_error(
-              "Singleton created before registration was complete.");
-        }
-      }
-    }
-
-    registrationComplete_ = true;
-  }
+  void registrationComplete();
 
   /**
    * Initialize all singletons which were marked as eager-initialized
@@ -387,49 +337,14 @@ class SingletonVault {
    * from constructors / create functions, as is the usual case when calling
    * for example `Singleton<Foo>::get_weak()`.
    */
-  void doEagerInit() {
-    std::unordered_set<detail::SingletonHolderBase*> singletonSet;
-    {
-      RWSpinLock::ReadHolder rh(&stateMutex_);
-      stateCheck(SingletonVaultState::Running);
-      if (UNLIKELY(!registrationComplete_)) {
-        throw std::logic_error("registrationComplete() not yet called");
-      }
-      singletonSet = eagerInitSingletons_; // copy set of pointers
-    }
-
-    for (auto *single : singletonSet) {
-      single->createInstance();
-    }
-  }
+  void doEagerInit();
 
   /**
    * Schedule eager singletons' initializations through the given executor.
    * Return a future which is fulfilled after all the initialization functions
    * complete.
    */
-  Future<Unit> doEagerInitVia(Executor* exe) {
-    std::unordered_set<detail::SingletonHolderBase*> singletonSet;
-    {
-      RWSpinLock::ReadHolder rh(&stateMutex_);
-      stateCheck(SingletonVaultState::Running);
-      if (UNLIKELY(!registrationComplete_)) {
-        throw std::logic_error("registrationComplete() not yet called");
-      }
-      singletonSet = eagerInitSingletons_; // copy set of pointers
-    }
-
-    std::vector<Future<Unit>> resultFutures;
-    for (auto* single : singletonSet) {
-      resultFutures.emplace_back(via(exe).then([single] {
-        if (!single->creationStarted()) {
-          single->createInstance();
-        }
-      }));
-    }
-
-    return collectAll(resultFutures).via(exe).then();
-  }
+  Future<Unit> doEagerInitVia(Executor* exe);
 
   // Destroy all singletons; when complete, the vault can't create
   // singletons once again until reenableInstances() is called.