proxygen
folly::SingletonVault Class Reference

#include <Singleton.h>

Classes

struct  ScopedExpunger
 

Public Types

enum  Type { Type::Strict, Type::Relaxed }
 
typedef std::function< void(void *)> TeardownFunc
 
typedef std::function< void *(void)> CreateFunc
 
typedef std::string(* StackTraceGetterPtr) ()
 

Public Member Functions

 SingletonVault (Type type=defaultVaultType())
 
 ~SingletonVault ()
 
void registerSingleton (detail::SingletonHolderBase *entry)
 
void addEagerInitSingleton (detail::SingletonHolderBase *entry)
 
void registrationComplete ()
 
void doEagerInit ()
 
void doEagerInitVia (Executor &exe, folly::Baton<> *done=nullptr)
 
void destroyInstances ()
 
void reenableInstances ()
 
size_t registeredSingletonCount () const
 
bool eagerInitComplete () const
 
size_t livingSingletonCount () const
 
void setType (Type type)
 

Static Public Member Functions

static Type defaultVaultType ()
 
static SingletonVaultsingleton ()
 
template<typename VaultTag = detail::DefaultTag>
static SingletonVaultsingleton ()
 
static std::atomic< StackTraceGetterPtr > & stackTraceGetter ()
 

Private Types

typedef std::unordered_map< detail::TypeDescriptor, detail::SingletonHolderBase *, detail::TypeDescriptorHasherSingletonMap
 

Static Private Member Functions

static void scheduleDestroyInstances ()
 

Private Attributes

Synchronized< SingletonMap, SharedMutexSuppressTSANsingletons_
 
Synchronized< std::unordered_set< detail::SingletonHolderBase * >, SharedMutexSuppressTSANeagerInitSingletons_
 
Synchronized< std::vector< detail::TypeDescriptor >, SharedMutexSuppressTSANcreationOrder_
 
Synchronized< detail::SingletonVaultState, SharedMutexReadPrioritystate_
 
Type type_
 

Friends

template<typename T >
struct detail::SingletonHolder
 

Detailed Description

Definition at line 375 of file Singleton.h.

Member Typedef Documentation

typedef std::function<void*(void)> folly::SingletonVault::CreateFunc

Definition at line 415 of file Singleton.h.

typedef std::string(* folly::SingletonVault::StackTraceGetterPtr) ()

Definition at line 508 of file Singleton.h.

typedef std::function<void(void*)> folly::SingletonVault::TeardownFunc

Definition at line 414 of file Singleton.h.

Member Enumeration Documentation

Enumerator
Strict 
Relaxed 

Definition at line 377 of file Singleton.h.

377  {
378  Strict, // Singletons can't be created before registrationComplete()
379  Relaxed, // Singletons can be created before registrationComplete()
380  };

Constructor & Destructor Documentation

folly::SingletonVault::SingletonVault ( Type  type = defaultVaultType())
inlineexplicit

Definition at line 409 of file Singleton.h.

409 : type_(type) {}
PskType type
folly::SingletonVault::~SingletonVault ( )

Definition at line 221 of file Singleton.cpp.

221  {
223 }

Member Function Documentation

void folly::SingletonVault::addEagerInitSingleton ( 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.

Definition at line 238 of file Singleton.cpp.

References CHECK_THROW, folly::detail::SingletonVaultState::Running, folly::detail::SingletonHolderBase::type(), and UNLIKELY.

238  {
239  auto state = state_.rlock();
241 
242  if (UNLIKELY(state->registrationComplete)) {
243  LOG(ERROR) << "Registering for eager-load after registrationComplete().";
244  }
245 
246  CHECK_THROW(singletons_.rlock()->count(entry->type()), std::logic_error);
247 
248  auto eagerInitSingletons = eagerInitSingletons_.wlock();
249  eagerInitSingletons->insert(entry);
250 }
Synchronized< std::unordered_set< detail::SingletonHolderBase * >, SharedMutexSuppressTSAN > eagerInitSingletons_
Definition: Singleton.h:550
#define CHECK_THROW(cond, E)
Definition: Exception.h:135
#define UNLIKELY(x)
Definition: Likely.h:48
state
Definition: http_parser.c:272
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
Synchronized< SingletonMap, SharedMutexSuppressTSAN > singletons_
Definition: Singleton.h:546
SingletonVault::Type folly::SingletonVault::defaultVaultType ( )
static

Definition at line 51 of file Singleton.cpp.

References folly::detail::singleton_hs_init_weak().

51  {
52 #if FOLLY_SINGLETON_HAVE_DLSYM
53  bool isPython = dlsym(RTLD_DEFAULT, "Py_Main");
54  bool isHaskel =
55  detail::singleton_hs_init_weak || dlsym(RTLD_DEFAULT, "hs_init");
56  bool isJVM = dlsym(RTLD_DEFAULT, "JNI_GetCreatedJavaVMs");
57  bool isD = dlsym(RTLD_DEFAULT, "_d_run_main");
58 
59  return isPython || isHaskel || isJVM || isD ? Type::Relaxed : Type::Strict;
60 #else
61  return Type::Relaxed;
62 #endif
63 }
static void singleton_hs_init_weak(int *argc, char **argv[]) __attribute__((__weakref__("hs_init")))
void folly::SingletonVault::destroyInstances ( )

Definition at line 328 of file Singleton.cpp.

References folly::detail::SingletonVaultState::Quiescing.

Referenced by folly::SingletonVault::ScopedExpunger::expunge(), registrationComplete(), scheduleDestroyInstances(), TEST(), and folly::Init::~Init().

328  {
329  auto stateW = state_.wlock();
330  if (stateW->state == detail::SingletonVaultState::Type::Quiescing) {
331  return;
332  }
334 
335  auto stateR = stateW.moveFromWriteToRead();
336  {
337  auto singletons = singletons_.rlock();
338  auto creationOrder = creationOrder_.rlock();
339 
340  CHECK_GE(singletons->size(), creationOrder->size());
341 
342  // Release all ReadMostlyMainPtrs at once
343  {
344  ReadMostlyMainPtrDeleter<> deleter;
345  for (auto& singleton_type : *creationOrder) {
346  singletons->at(singleton_type)->preDestroyInstance(deleter);
347  }
348  }
349 
350  for (auto type_iter = creationOrder->rbegin();
351  type_iter != creationOrder->rend();
352  ++type_iter) {
353  singletons->at(*type_iter)->destroyInstance();
354  }
355 
356  for (auto& singleton_type : *creationOrder) {
357  auto instance = singletons->at(singleton_type);
358  if (!instance->hasLiveInstance()) {
359  continue;
360  }
361 
362  fatalHelper.leakedSingletons_.push_back(instance->type());
363  }
364  }
365 
366  {
367  auto creationOrder = creationOrder_.wlock();
368  creationOrder->clear();
369  }
370 }
Synchronized< std::vector< detail::TypeDescriptor >, SharedMutexSuppressTSAN > creationOrder_
Definition: Singleton.h:552
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
Synchronized< SingletonMap, SharedMutexSuppressTSAN > singletons_
Definition: Singleton.h:546
void folly::SingletonVault::doEagerInit ( )

Initialize all singletons which were marked as eager-initialized (using shouldEagerInit()). No return value. Propagates exceptions from constructors / create functions, as is the usual case when calling for example Singleton<Foo>::get_weak().

Definition at line 276 of file Singleton.cpp.

References folly::detail::SingletonVaultState::Running, single, and UNLIKELY.

276  {
277  {
278  auto state = state_.rlock();
280  if (UNLIKELY(!state->registrationComplete)) {
281  throw std::logic_error("registrationComplete() not yet called");
282  }
283  }
284 
285  auto eagerInitSingletons = eagerInitSingletons_.rlock();
286  for (auto* single : *eagerInitSingletons) {
287  single->createInstance();
288  }
289 }
Synchronized< std::unordered_set< detail::SingletonHolderBase * >, SharedMutexSuppressTSAN > eagerInitSingletons_
Definition: Singleton.h:550
countdownsingle single
#define UNLIKELY(x)
Definition: Likely.h:48
state
Definition: http_parser.c:272
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
void folly::SingletonVault::doEagerInitVia ( Executor exe,
folly::Baton<> *  done = nullptr 
)

Schedule eager singletons' initializations through the given executor. If baton ptr is not null, its post method is called after all early initialization has completed.

If exceptions are thrown during initialization, this method will still post the baton to indicate completion. The exception will not propagate and future attempts to try_get or get_weak the failed singleton will retry initialization.

Sample usage:

folly::IOThreadPoolExecutor executor(max_concurrency_level); folly::Baton<> done; doEagerInitVia(executor, &done); done.wait(); // or 'try_wait_for', etc.

Definition at line 291 of file Singleton.cpp.

References folly::Executor::add(), folly::Baton< MayBlock, Atom >::post(), folly::detail::SingletonVaultState::Running, SCOPE_EXIT, single, and UNLIKELY.

291  {
292  {
293  auto state = state_.rlock();
295  if (UNLIKELY(!state->registrationComplete)) {
296  throw std::logic_error("registrationComplete() not yet called");
297  }
298  }
299 
300  auto eagerInitSingletons = eagerInitSingletons_.rlock();
301  auto countdown =
302  std::make_shared<std::atomic<size_t>>(eagerInitSingletons->size());
303  for (auto* single : *eagerInitSingletons) {
304  // countdown is retained by shared_ptr, and will be alive until last lambda
305  // is done. notifyBaton is provided by the caller, and expected to remain
306  // present (if it's non-nullptr). singletonSet can go out of scope but
307  // its values, which are SingletonHolderBase pointers, are alive as long as
308  // SingletonVault is not being destroyed.
309  exe.add([=] {
310  // decrement counter and notify if requested, whether initialization
311  // was successful, was skipped (already initialized), or exception thrown.
312  SCOPE_EXIT {
313  if (--(*countdown) == 0) {
314  if (done != nullptr) {
315  done->post();
316  }
317  }
318  };
319  // if initialization is in progress in another thread, don't try to init
320  // here. Otherwise the current thread will block on 'createInstance'.
321  if (!single->creationStarted()) {
322  single->createInstance();
323  }
324  });
325  }
326 }
#define SCOPE_EXIT
Definition: ScopeGuard.h:274
Synchronized< std::unordered_set< detail::SingletonHolderBase * >, SharedMutexSuppressTSAN > eagerInitSingletons_
Definition: Singleton.h:550
void post() noexcept
Definition: Baton.h:123
countdownsingle single
InlineExecutor exe
Definition: Benchmark.cpp:337
#define UNLIKELY(x)
Definition: Likely.h:48
state
Definition: http_parser.c:272
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
bool folly::SingletonVault::eagerInitComplete ( ) const

Flips to true if eager initialization was used, and has completed. Never set to true if "doEagerInit()" or "doEagerInitVia" never called.

size_t folly::SingletonVault::livingSingletonCount ( ) const
inline

Definition at line 480 of file Singleton.h.

480  {
481  auto singletons = singletons_.rlock();
482 
483  size_t ret = 0;
484  for (const auto& p : *singletons) {
485  if (p.second->hasLiveInstance()) {
486  ++ret;
487  }
488  }
489 
490  return ret;
491  }
Synchronized< SingletonMap, SharedMutexSuppressTSAN > singletons_
Definition: Singleton.h:546
void folly::SingletonVault::reenableInstances ( )
size_t folly::SingletonVault::registeredSingletonCount ( ) const
inline

Definition at line 470 of file Singleton.h.

470  {
471  return singletons_.rlock()->size();
472  }
Synchronized< SingletonMap, SharedMutexSuppressTSAN > singletons_
Definition: Singleton.h:546
void folly::SingletonVault::registerSingleton ( detail::SingletonHolderBase entry)

Definition at line 225 of file Singleton.cpp.

References CHECK_THROW, folly::detail::SingletonVaultState::Running, folly::detail::SingletonHolderBase::type(), and UNLIKELY.

225  {
226  auto state = state_.rlock();
228 
229  if (UNLIKELY(state->registrationComplete)) {
230  LOG(ERROR) << "Registering singleton after registrationComplete().";
231  }
232 
233  auto singletons = singletons_.wlock();
234  CHECK_THROW(
235  singletons->emplace(entry->type(), entry).second, std::logic_error);
236 }
#define CHECK_THROW(cond, E)
Definition: Exception.h:135
#define UNLIKELY(x)
Definition: Likely.h:48
state
Definition: http_parser.c:272
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
Synchronized< SingletonMap, SharedMutexSuppressTSAN > singletons_
Definition: Singleton.h:546
void folly::SingletonVault::registrationComplete ( )

Definition at line 252 of file Singleton.cpp.

References destroyInstances(), folly::detail::SingletonVaultState::Running, singleton(), and type_.

Referenced by folly::init().

252  {
253  std::atexit([]() { SingletonVault::singleton()->destroyInstances(); });
254 
255  auto state = state_.wlock();
257 
258  if (state->registrationComplete) {
259  return;
260  }
261 
262  auto singletons = singletons_.rlock();
263  if (type_ == Type::Strict) {
264  for (const auto& p : *singletons) {
265  if (p.second->hasLiveInstance()) {
266  throw std::runtime_error(
267  "Singleton " + p.first.name() +
268  " created before registration was complete.");
269  }
270  }
271  }
272 
273  state->registrationComplete = true;
274 }
static SingletonVault * singleton()
Definition: Singleton.h:495
state
Definition: http_parser.c:272
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
Synchronized< SingletonMap, SharedMutexSuppressTSAN > singletons_
Definition: Singleton.h:546
void folly::SingletonVault::scheduleDestroyInstances ( )
staticprivate
void folly::SingletonVault::setType ( Type  type)
inline

Definition at line 516 of file Singleton.h.

References type, and type_.

516  {
517  type_ = type;
518  }
PskType type
static SingletonVault* folly::SingletonVault::singleton ( )
inlinestatic

Definition at line 495 of file Singleton.h.

Referenced by folly::init(), registrationComplete(), scheduleDestroyInstances(), TEST(), and folly::Init::~Init().

495  {
496  return singleton<>();
497  }
template<typename VaultTag = detail::DefaultTag>
static SingletonVault* folly::SingletonVault::singleton ( )
inlinestatic

Definition at line 502 of file Singleton.h.

502  {
503  /* library-local */ static auto vault =
504  detail::createGlobal<SingletonVault, VaultTag>();
505  return vault;
506  }
static std::atomic<StackTraceGetterPtr>& folly::SingletonVault::stackTraceGetter ( )
inlinestatic

Definition at line 510 of file Singleton.h.

Referenced by proxygen::logging_details::getStackTrace(), scheduleDestroyInstances(), folly::detail::singletonPrintDestructionStackTrace(), folly::detail::singletonWarnCreateBeforeRegistrationCompleteAndAbort(), folly::detail::singletonWarnCreateUnregisteredAndAbort(), and folly::detail::singletonWarnLeakyInstantiatingNotRegisteredAndAbort().

510  {
511  /* library-local */ static auto stackTraceGetterPtr = detail::
512  createGlobal<std::atomic<StackTraceGetterPtr>, SingletonVault>();
513  return *stackTraceGetterPtr;
514  }
SingletonVault(Type type=defaultVaultType())
Definition: Singleton.h:409

Friends And Related Function Documentation

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

Definition at line 522 of file Singleton.h.

Member Data Documentation

Synchronized<std::vector<detail::TypeDescriptor>, SharedMutexSuppressTSAN> folly::SingletonVault::creationOrder_
private

Definition at line 552 of file Singleton.h.

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

Synchronized< std::unordered_set<detail::SingletonHolderBase*>, SharedMutexSuppressTSAN> folly::SingletonVault::eagerInitSingletons_
private

Definition at line 550 of file Singleton.h.

Synchronized<SingletonMap, SharedMutexSuppressTSAN> folly::SingletonVault::singletons_
private

Definition at line 546 of file Singleton.h.

Synchronized<detail::SingletonVaultState, SharedMutexReadPriority> folly::SingletonVault::state_
private

Definition at line 557 of file Singleton.h.

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

Type folly::SingletonVault::type_
private

Definition at line 559 of file Singleton.h.

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


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