Fix SimplerObservable build with -Werror=unused-local-typedefs
[folly.git] / folly / Singleton.cpp
index 66321bfdc1e47c4e9a37285b405d8b0bb39cef51..c1031944313c610dfbfc33e97062119295e89c40 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <folly/Singleton.h>
 
 #include <atomic>
+#include <cstdio>
+#include <cstdlib>
+#include <sstream>
 #include <string>
 
+#include <folly/FileUtil.h>
 #include <folly/ScopeGuard.h>
 
 namespace folly {
 
 namespace detail {
 
-constexpr std::chrono::seconds SingletonHolderBase::kDestroyWaitTime;
-
+[[noreturn]] void singletonWarnDoubleRegistrationAndAbort(
+    const TypeDescriptor& type) {
+  // Not using LOG(FATAL) or std::cerr because they may not be initialized yet.
+  std::ostringstream o;
+  o << "Double registration of singletons of the same "
+    << "underlying type; check for multiple definitions "
+    << "of type folly::Singleton<" << type.name() << ">" << std::endl;
+  auto s = o.str();
+  writeFull(STDERR_FILENO, s.data(), s.size());
+  std::abort();
+}
 }
 
 namespace {
@@ -65,8 +78,7 @@ void SingletonVault::registerSingleton(detail::SingletonHolderBase* entry) {
   stateCheck(SingletonVaultState::Running);
 
   if (UNLIKELY(registrationComplete_)) {
-    throw std::logic_error(
-      "Registering singleton after registrationComplete().");
+    LOG(ERROR) << "Registering singleton after registrationComplete().";
   }
 
   RWSpinLock::ReadHolder rhMutex(&mutex_);
@@ -83,8 +95,7 @@ void SingletonVault::addEagerInitSingleton(detail::SingletonHolderBase* entry) {
   stateCheck(SingletonVaultState::Running);
 
   if (UNLIKELY(registrationComplete_)) {
-    throw std::logic_error(
-        "Registering for eager-load after registrationComplete().");
+    LOG(ERROR) << "Registering for eager-load after registrationComplete().";
   }
 
   RWSpinLock::ReadHolder rhMutex(&mutex_);
@@ -182,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) {
@@ -213,6 +232,10 @@ void SingletonVault::reenableInstances() {
 }
 
 void SingletonVault::scheduleDestroyInstances() {
+  // Add a dependency on folly::ThreadLocal to make sure all its static
+  // singletons are initalized first.
+  threadlocal_detail::StaticMeta<void>::instance();
+
   class SingletonVaultDestructor {
    public:
     ~SingletonVaultDestructor() {