proxygen
folly::detail::SingletonHolder< T > Struct Template Reference

#include <Singleton.h>

Inheritance diagram for folly::detail::SingletonHolder< T >:
folly::detail::SingletonHolderBase

Public Types

typedef std::function< void(T *)> TeardownFunc
 
typedef std::function< T *(void)> CreateFunc
 

Public Member Functions

Tget ()
 
std::weak_ptr< Tget_weak ()
 
std::shared_ptr< Ttry_get ()
 
folly::ReadMostlySharedPtr< Ttry_get_fast ()
 
void vivify ()
 
void registerSingleton (CreateFunc c, TeardownFunc t)
 
void registerSingletonMock (CreateFunc c, TeardownFunc t)
 
bool hasLiveInstance () override
 
void createInstance () override
 
bool creationStarted () override
 
void preDestroyInstance (ReadMostlyMainPtrDeleter<> &) override
 
void destroyInstance () override
 
- Public Member Functions inherited from folly::detail::SingletonHolderBase
 SingletonHolderBase (TypeDescriptor typeDesc)
 
virtual ~SingletonHolderBase ()=default
 
TypeDescriptor type () const
 

Static Public Member Functions

template<typename Tag , typename VaultTag >
static SingletonHolder< T > & singleton ()
 

Private Types

enum  SingletonHolderState { SingletonHolderState::NotRegistered, SingletonHolderState::Dead, SingletonHolderState::Living }
 

Private Member Functions

 SingletonHolder (TypeDescriptor type, SingletonVault &vault)
 
 SingletonHolder (const SingletonHolder &)=delete
 
SingletonHolderoperator= (const SingletonHolder &)=delete
 
SingletonHolderoperator= (SingletonHolder &&)=delete
 
 SingletonHolder (SingletonHolder &&)=delete
 

Private Attributes

SingletonVaultvault_
 
std::mutex mutex_
 
std::atomic< SingletonHolderStatestate_ {SingletonHolderState::NotRegistered}
 
std::atomic< std::thread::id > creating_thread_ {}
 
folly::ReadMostlyMainPtr< Tinstance_
 
folly::ReadMostlySharedPtr< Tinstance_copy_
 
std::weak_ptr< Tinstance_weak_
 
folly::ReadMostlyWeakPtr< Tinstance_weak_fast_
 
std::shared_ptr< folly::Baton<> > destroy_baton_
 
Tinstance_ptr_ = nullptr
 
CreateFunc create_ = nullptr
 
TeardownFunc teardown_ = nullptr
 
std::shared_ptr< std::atomic< bool > > print_destructor_stack_trace_
 

Detailed Description

template<typename T>
struct folly::detail::SingletonHolder< T >

Definition at line 302 of file Singleton.h.

Member Typedef Documentation

template<typename T>
typedef std::function<T*(void)> folly::detail::SingletonHolder< T >::CreateFunc

Definition at line 305 of file Singleton.h.

template<typename T>
typedef std::function<void(T*)> folly::detail::SingletonHolder< T >::TeardownFunc

Definition at line 304 of file Singleton.h.

Member Enumeration Documentation

template<typename T>
enum folly::detail::SingletonHolder::SingletonHolderState
strongprivate
Enumerator
NotRegistered 
Dead 
Living 

Definition at line 327 of file Singleton.h.

327  {
328  NotRegistered,
329  Dead,
330  Living,
331  };

Constructor & Destructor Documentation

template<typename T >
folly::detail::SingletonHolder< T >::SingletonHolder ( TypeDescriptor  type,
SingletonVault vault 
)
private

Definition at line 181 of file Singleton-inl.h.

184  : SingletonHolderBase(typeDesc), vault_(vault) {}
SingletonHolderBase(TypeDescriptor typeDesc)
Definition: Singleton.h:282
template<typename T>
folly::detail::SingletonHolder< T >::SingletonHolder ( const SingletonHolder< T > &  )
privatedelete
template<typename T>
folly::detail::SingletonHolder< T >::SingletonHolder ( SingletonHolder< T > &&  )
privatedelete

Member Function Documentation

template<typename T >
void folly::detail::SingletonHolder< T >::createInstance ( )
overridevirtual

Implements folly::detail::SingletonHolderBase.

Definition at line 203 of file Singleton-inl.h.

References folly::detail::SingletonHolder< T >::create_, folly::detail::SingletonHolder< T >::creating_thread_, folly::SingletonVault::creationOrder_, folly::detail::SingletonHolder< T >::destroy_baton_, folly::detail::SingletonHolder< T >::instance_, folly::detail::SingletonHolder< T >::instance_ptr_, folly::detail::SingletonHolder< T >::instance_weak_, folly::detail::SingletonHolder< T >::instance_weak_fast_, folly::detail::SingletonHolder< T >::Living, folly::gen::move, folly::detail::SingletonHolder< T >::mutex_, folly::detail::SingletonHolder< T >::NotRegistered, folly::detail::SingletonHolder< T >::print_destructor_stack_trace_, folly::detail::SingletonVaultState::Quiescing, folly::SingletonVault::Relaxed, folly::ReadMostlyMainPtr< T, RefCount >::reset(), folly::SingletonVault::scheduleDestroyInstances(), SCOPE_EXIT, folly::detail::singletonPrintDestructionStackTrace(), folly::detail::singletonWarnCreateBeforeRegistrationCompleteAndAbort(), folly::detail::singletonWarnCreateCircularDependencyAndAbort(), folly::detail::singletonWarnCreateUnregisteredAndAbort(), folly::detail::SingletonHolder< T >::state_, folly::SingletonVault::state_, folly::T, folly::detail::SingletonHolderBase::type(), folly::SingletonVault::type_, and folly::detail::SingletonHolder< T >::vault_.

203  {
204  if (creating_thread_.load(std::memory_order_acquire) ==
205  std::this_thread::get_id()) {
207  }
208 
209  std::lock_guard<std::mutex> entry_lock(mutex_);
210  if (state_.load(std::memory_order_acquire) == SingletonHolderState::Living) {
211  return;
212  }
213  if (state_.load(std::memory_order_acquire) ==
216  }
217 
218  if (state_.load(std::memory_order_acquire) == SingletonHolderState::Living) {
219  return;
220  }
221 
222  SCOPE_EXIT {
223  // Clean up creator thread when complete, and also, in case of errors here,
224  // so that subsequent attempts don't think this is still in the process of
225  // being built.
226  creating_thread_.store(std::thread::id(), std::memory_order_release);
227  };
228 
229  creating_thread_.store(std::this_thread::get_id(), std::memory_order_release);
230 
231  auto state = vault_.state_.rlock();
233  !state->registrationComplete) {
235  }
237  return;
238  }
239 
240  auto destroy_baton = std::make_shared<folly::Baton<>>();
241  auto print_destructor_stack_trace =
242  std::make_shared<std::atomic<bool>>(false);
243 
244  // Can't use make_shared -- no support for a custom deleter, sadly.
245  std::shared_ptr<T> instance(
246  create_(),
247  [destroy_baton, print_destructor_stack_trace, type = type()](T*) mutable {
248  destroy_baton->post();
249  if (print_destructor_stack_trace->load()) {
251  }
252  });
253 
254  // We should schedule destroyInstances() only after the singleton was
255  // created. This will ensure it will be destroyed before singletons,
256  // not managed by folly::Singleton, which were initialized in its
257  // constructor
259 
260  instance_weak_ = instance;
261  instance_ptr_ = instance.get();
262  instance_.reset(std::move(instance));
264 
265  destroy_baton_ = std::move(destroy_baton);
266  print_destructor_stack_trace_ = std::move(print_destructor_stack_trace);
267 
268  // This has to be the last step, because once state is Living other threads
269  // may access instance and instance_weak w/o synchronization.
270  state_.store(SingletonHolderState::Living, std::memory_order_release);
271 
272  vault_.creationOrder_.wlock()->push_back(type());
273 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void singletonWarnCreateUnregisteredAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:133
void singletonWarnCreateCircularDependencyAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:128
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
folly::std T
folly::ReadMostlyMainPtr< T > instance_
Definition: Singleton.h:349
std::shared_ptr< folly::Baton<> > destroy_baton_
Definition: Singleton.h:360
folly::ReadMostlyWeakPtr< T > instance_weak_fast_
Definition: Singleton.h:358
std::atomic< std::thread::id > creating_thread_
Definition: Singleton.h:343
static void scheduleDestroyInstances()
Definition: Singleton.cpp:380
std::weak_ptr< T > instance_weak_
Definition: Singleton.h:356
void singletonWarnCreateBeforeRegistrationCompleteAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:143
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
TypeDescriptor type() const
Definition: Singleton.h:285
void singletonPrintDestructionStackTrace(const TypeDescriptor &type)
Definition: Singleton.cpp:159
std::shared_ptr< std::atomic< bool > > print_destructor_stack_trace_
Definition: Singleton.h:365
Synchronized< std::vector< detail::TypeDescriptor >, SharedMutexSuppressTSAN > creationOrder_
Definition: Singleton.h:552
state
Definition: http_parser.c:272
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
template<typename T >
bool folly::detail::SingletonHolder< T >::creationStarted ( )
overridevirtual

Implements folly::detail::SingletonHolderBase.

Definition at line 187 of file Singleton-inl.h.

References folly::detail::SingletonHolder< T >::creating_thread_, folly::detail::SingletonHolder< T >::Living, and folly::detail::SingletonHolder< T >::state_.

187  {
188  // If alive, then creation was of course started.
189  // This is flipped after creating_thread_ was set, and before it was reset.
190  if (state_.load(std::memory_order_acquire) == SingletonHolderState::Living) {
191  return true;
192  }
193 
194  // Not yet built. Is it currently in progress?
195  if (creating_thread_.load(std::memory_order_acquire) != std::thread::id()) {
196  return true;
197  }
198 
199  return false;
200 }
std::atomic< std::thread::id > creating_thread_
Definition: Singleton.h:343
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
template<typename T >
void folly::detail::SingletonHolder< T >::destroyInstance ( )
overridevirtual

Implements folly::detail::SingletonHolderBase.

Definition at line 163 of file Singleton-inl.h.

References folly::detail::singletonWarnDestroyInstanceLeak(), and type.

163  {
165  instance_.reset();
167  if (destroy_baton_) {
168  constexpr std::chrono::seconds kDestroyWaitTime{5};
169  auto last_reference_released =
170  destroy_baton_->try_wait_for(kDestroyWaitTime);
171  if (last_reference_released) {
173  } else {
174  print_destructor_stack_trace_->store(true);
176  }
177  }
178 }
folly::ReadMostlyMainPtr< T > instance_
Definition: Singleton.h:349
std::shared_ptr< folly::Baton<> > destroy_baton_
Definition: Singleton.h:360
void singletonWarnDestroyInstanceLeak(const TypeDescriptor &type, const void *ptr)
Definition: Singleton.cpp:115
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
TypeDescriptor type() const
Definition: Singleton.h:285
std::shared_ptr< std::atomic< bool > > print_destructor_stack_trace_
Definition: Singleton.h:365
folly::ReadMostlySharedPtr< T > instance_copy_
Definition: Singleton.h:351
template<typename T >
T * folly::detail::SingletonHolder< T >::get ( )
inline

Definition at line 93 of file Singleton-inl.h.

References LIKELY, folly::detail::singletonThrowGetInvokedAfterDestruction(), and type.

93  {
94  if (LIKELY(
95  state_.load(std::memory_order_acquire) ==
97  return instance_ptr_;
98  }
100 
101  if (instance_weak_.expired()) {
103  }
104 
105  return instance_ptr_;
106 }
#define LIKELY(x)
Definition: Likely.h:47
void singletonThrowGetInvokedAfterDestruction(const TypeDescriptor &type)
Definition: Singleton.cpp:181
std::weak_ptr< T > instance_weak_
Definition: Singleton.h:356
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
TypeDescriptor type() const
Definition: Singleton.h:285
template<typename T >
std::weak_ptr< T > folly::detail::SingletonHolder< T >::get_weak ( )
inline

Definition at line 109 of file Singleton-inl.h.

References UNLIKELY.

109  {
110  if (UNLIKELY(
111  state_.load(std::memory_order_acquire) !=
113  createInstance();
114  }
115 
116  return instance_weak_;
117 }
std::weak_ptr< T > instance_weak_
Definition: Singleton.h:356
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
#define UNLIKELY(x)
Definition: Likely.h:48
template<typename T >
bool folly::detail::SingletonHolder< T >::hasLiveInstance ( )
overridevirtual

Implements folly::detail::SingletonHolderBase.

Definition at line 151 of file Singleton-inl.h.

151  {
152  return !instance_weak_.expired();
153 }
std::weak_ptr< T > instance_weak_
Definition: Singleton.h:356
template<typename T>
SingletonHolder& folly::detail::SingletonHolder< T >::operator= ( const SingletonHolder< T > &  )
privatedelete
template<typename T>
SingletonHolder& folly::detail::SingletonHolder< T >::operator= ( SingletonHolder< T > &&  )
privatedelete
template<typename T >
void folly::detail::SingletonHolder< T >::preDestroyInstance ( ReadMostlyMainPtrDeleter<> &  deleter)
overridevirtual

Implements folly::detail::SingletonHolderBase.

Definition at line 156 of file Singleton-inl.h.

References folly::ReadMostlyMainPtrDeleter< RefCount >::add(), and folly::gen::move.

157  {
159  deleter.add(std::move(instance_));
160 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
folly::ReadMostlyMainPtr< T > instance_
Definition: Singleton.h:349
folly::ReadMostlySharedPtr< T > instance_copy_
Definition: Singleton.h:351
template<typename T >
void folly::detail::SingletonHolder< T >::registerSingleton ( CreateFunc  c,
TeardownFunc  t 
)

Definition at line 36 of file Singleton-inl.h.

References folly::gen::move, mutex_, folly::detail::singletonWarnDoubleRegistrationAndAbort(), and type.

36  {
37  std::lock_guard<std::mutex> entry_lock(mutex_);
38 
40  /* Possible causes:
41  *
42  * You have two instances of the same
43  * folly::Singleton<Class>. Probably because you define the
44  * singleton in a header included in multiple places? In general,
45  * folly::Singleton shouldn't be in the header, only off in some
46  * anonymous namespace in a cpp file. Code needing the singleton
47  * will find it when that code references folly::Singleton<Class>.
48  *
49  * Alternatively, you could have 2 singletons with the same type
50  * defined with a different name in a .cpp (source) file. For
51  * example:
52  *
53  * Singleton<int> a([] { return new int(3); });
54  * Singleton<int> b([] { return new int(4); });
55  *
56  * Adding tags should fix this (see documentation in the header).
57  *
58  */
60  }
61 
62  create_ = std::move(c);
64 
66 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void singletonWarnDoubleRegistrationAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:77
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
TypeDescriptor type() const
Definition: Singleton.h:285
char c
template<typename T >
void folly::detail::SingletonHolder< T >::registerSingletonMock ( CreateFunc  c,
TeardownFunc  t 
)

Definition at line 69 of file Singleton-inl.h.

References folly::gen::move, mutex_, folly::detail::singletonWarnRegisterMockEarlyAndAbort(), and type.

69  {
72  }
75  }
76 
77  {
78  auto creationOrder = vault_.creationOrder_.wlock();
79 
80  auto it = std::find(creationOrder->begin(), creationOrder->end(), type());
81  if (it != creationOrder->end()) {
82  creationOrder->erase(it);
83  }
84  }
85 
86  std::lock_guard<std::mutex> entry_lock(mutex_);
87 
88  create_ = std::move(c);
90 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void singletonWarnRegisterMockEarlyAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:109
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
TypeDescriptor type() const
Definition: Singleton.h:285
char c
Synchronized< std::vector< detail::TypeDescriptor >, SharedMutexSuppressTSAN > creationOrder_
Definition: Singleton.h:552
template<typename T >
template<typename Tag , typename VaultTag >
SingletonHolder< T > & folly::detail::SingletonHolder< T >::singleton ( )
inlinestatic

Definition at line 23 of file Singleton-inl.h.

References folly::detail::singletonWarnDoubleRegistrationAndAbort(), folly::T, and type.

23  {
24  /* library-local */ static auto entry =
25  createGlobal<SingletonHolder<T>, std::pair<Tag, VaultTag>>([]() {
26  return new SingletonHolder<T>(
27  {typeid(T), typeid(Tag)}, *SingletonVault::singleton<VaultTag>());
28  });
29  return *entry;
30 }
folly::std T
template<typename T >
std::shared_ptr< T > folly::detail::SingletonHolder< T >::try_get ( )
inline

Definition at line 120 of file Singleton-inl.h.

References UNLIKELY.

120  {
121  if (UNLIKELY(
122  state_.load(std::memory_order_acquire) !=
124  createInstance();
125  }
126 
127  return instance_weak_.lock();
128 }
std::weak_ptr< T > instance_weak_
Definition: Singleton.h:356
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
#define UNLIKELY(x)
Definition: Likely.h:48
template<typename T >
folly::ReadMostlySharedPtr< T > folly::detail::SingletonHolder< T >::try_get_fast ( )
inline

Definition at line 131 of file Singleton-inl.h.

References UNLIKELY.

131  {
132  if (UNLIKELY(
133  state_.load(std::memory_order_acquire) !=
135  createInstance();
136  }
137 
138  return instance_weak_fast_.lock();
139 }
folly::ReadMostlyWeakPtr< T > instance_weak_fast_
Definition: Singleton.h:358
ReadMostlySharedPtr< T, RefCount > lock()
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
#define UNLIKELY(x)
Definition: Likely.h:48
template<typename T >
void folly::detail::SingletonHolder< T >::vivify ( )
inline

Definition at line 142 of file Singleton-inl.h.

References UNLIKELY.

142  {
143  if (UNLIKELY(
144  state_.load(std::memory_order_relaxed) !=
146  createInstance();
147  }
148 }
std::atomic< SingletonHolderState > state_
Definition: Singleton.h:340
#define UNLIKELY(x)
Definition: Likely.h:48

Member Data Documentation

template<typename T>
CreateFunc folly::detail::SingletonHolder< T >::create_ = nullptr
private

Definition at line 362 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
std::atomic<std::thread::id> folly::detail::SingletonHolder< T >::creating_thread_ {}
private
template<typename T>
std::shared_ptr<folly::Baton<> > folly::detail::SingletonHolder< T >::destroy_baton_
private

Definition at line 360 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
folly::ReadMostlyMainPtr<T> folly::detail::SingletonHolder< T >::instance_
private

Definition at line 349 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
folly::ReadMostlySharedPtr<T> folly::detail::SingletonHolder< T >::instance_copy_
private

Definition at line 351 of file Singleton.h.

template<typename T>
T* folly::detail::SingletonHolder< T >::instance_ptr_ = nullptr
private

Definition at line 361 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
std::weak_ptr<T> folly::detail::SingletonHolder< T >::instance_weak_
private

Definition at line 356 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
folly::ReadMostlyWeakPtr<T> folly::detail::SingletonHolder< T >::instance_weak_fast_
private

Definition at line 358 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
std::mutex folly::detail::SingletonHolder< T >::mutex_
private

Definition at line 336 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
std::shared_ptr<std::atomic<bool> > folly::detail::SingletonHolder< T >::print_destructor_stack_trace_
private

Definition at line 365 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().

template<typename T>
TeardownFunc folly::detail::SingletonHolder< T >::teardown_ = nullptr
private

Definition at line 363 of file Singleton.h.

template<typename T>
SingletonVault& folly::detail::SingletonHolder< T >::vault_
private

Definition at line 333 of file Singleton.h.

Referenced by folly::detail::SingletonHolder< T >::createInstance().


The documentation for this struct was generated from the following files: