Add additional points to configure help output
[folly.git] / folly / Singleton-inl.h
index 83dbd2f6eb07bec7ae88271f28363a6e8b1bcddb..207a0f7dc32536b3cdf2ff11107b2598b55d2ccf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ namespace detail {
 template <typename T>
 template <typename Tag, typename VaultTag>
 SingletonHolder<T>& SingletonHolder<T>::singleton() {
-  static auto entry =
+  /* library-local */ static auto entry =
       createGlobal<SingletonHolder<T>, std::pair<Tag, VaultTag>>([]() {
         return new SingletonHolder<T>({typeid(T), typeid(Tag)},
                                       *SingletonVault::singleton<VaultTag>());
@@ -72,12 +72,11 @@ void SingletonHolder<T>::registerSingletonMock(CreateFunc c, TeardownFunc t) {
   destroyInstance();
 
   {
-    RWSpinLock::WriteHolder wh(&vault_.mutex_);
+    auto creationOrder = vault_.creationOrder_.wlock();
 
-    auto it = std::find(
-        vault_.creation_order_.begin(), vault_.creation_order_.end(), type());
-    if (it != vault_.creation_order_.end()) {
-      vault_.creation_order_.erase(it);
+    auto it = std::find(creationOrder->begin(), creationOrder->end(), type());
+    if (it != creationOrder->end()) {
+      creationOrder->erase(it);
     }
   }
 
@@ -224,8 +223,19 @@ void SingletonHolder<T>::createInstance() {
 
   creating_thread_.store(std::this_thread::get_id(), std::memory_order_release);
 
-  RWSpinLock::ReadHolder rh(&vault_.stateMutex_);
-  if (vault_.state_ == SingletonVault::SingletonVaultState::Quiescing) {
+  auto state = vault_.state_.rlock();
+  if (vault_.type_ != SingletonVault::Type::Relaxed &&
+      !state->registrationComplete) {
+    auto stack_trace_getter = SingletonVault::stackTraceGetter().load();
+    auto stack_trace = stack_trace_getter ? stack_trace_getter() : "";
+    if (!stack_trace.empty()) {
+      stack_trace = "Stack trace:\n" + stack_trace;
+    }
+
+    LOG(FATAL) << "Singleton " << type().name() << " requested before "
+               << "registrationComplete() call. " << stack_trace;
+  }
+  if (state->state == SingletonVault::SingletonVaultState::Quiescing) {
     return;
   }
 
@@ -275,10 +285,7 @@ void SingletonHolder<T>::createInstance() {
   // may access instance and instance_weak w/o synchronization.
   state_.store(SingletonHolderState::Living, std::memory_order_release);
 
-  {
-    RWSpinLock::WriteHolder wh(&vault_.mutex_);
-    vault_.creation_order_.push_back(type());
-  }
+  vault_.creationOrder_.wlock()->push_back(type());
 }
 
 }