proxygen
Singleton.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 // SingletonVault - a library to manage the creation and destruction
17 // of interdependent singletons.
18 //
19 // Recommended usage of this class: suppose you have a class
20 // called MyExpensiveService, and you only want to construct one (ie,
21 // it's a singleton), but you only want to construct it if it is used.
22 //
23 // In your .h file:
24 // class MyExpensiveService {
25 // // Caution - may return a null ptr during startup and shutdown.
26 // static std::shared_ptr<MyExpensiveService> getInstance();
27 // ....
28 // };
29 //
30 // In your .cpp file:
31 // namespace { struct PrivateTag {}; }
32 // static folly::Singleton<MyExpensiveService, PrivateTag> the_singleton;
33 // std::shared_ptr<MyExpensiveService> MyExpensiveService::getInstance() {
34 // return the_singleton.try_get();
35 // }
36 //
37 // Code in other modules can access it via:
38 //
39 // auto instance = MyExpensiveService::getInstance();
40 //
41 // Advanced usage and notes:
42 //
43 // You can also access a singleton instance with
44 // `Singleton<ObjectType, TagType>::try_get()`. We recommend
45 // that you prefer the form `the_singleton.try_get()` because it ensures that
46 // `the_singleton` is used and cannot be garbage-collected during linking: this
47 // is necessary because the constructor of `the_singleton` is what registers it
48 // to the SingletonVault.
49 //
50 // The singleton will be created on demand. If the constructor for
51 // MyExpensiveService actually makes use of *another* Singleton, then
52 // the right thing will happen -- that other singleton will complete
53 // construction before get() returns. However, in the event of a
54 // circular dependency, a runtime error will occur.
55 //
56 // You can have multiple singletons of the same underlying type, but
57 // each must be given a unique tag. If no tag is specified a default tag is
58 // used. We recommend that you use a tag from an anonymous namespace private to
59 // your implementation file, as this ensures that the singleton is only
60 // available via your interface and not also through Singleton<T>::try_get()
61 //
62 // namespace {
63 // struct Tag1 {};
64 // struct Tag2 {};
65 // folly::Singleton<MyExpensiveService> s_default;
66 // folly::Singleton<MyExpensiveService, Tag1> s1;
67 // folly::Singleton<MyExpensiveService, Tag2> s2;
68 // }
69 // ...
70 // MyExpensiveService* svc_default = s_default.get();
71 // MyExpensiveService* svc1 = s1.get();
72 // MyExpensiveService* svc2 = s2.get();
73 //
74 // By default, the singleton instance is constructed via new and
75 // deleted via delete, but this is configurable:
76 //
77 // namespace { folly::Singleton<MyExpensiveService> the_singleton(create,
78 // destroy); }
79 //
80 // Where create and destroy are functions, Singleton<T>::CreateFunc
81 // Singleton<T>::TeardownFunc.
82 //
83 // For example, if you need to pass arguments to your class's constructor:
84 // class X {
85 // public:
86 // X(int a1, std::string a2);
87 // // ...
88 // }
89 // Make your singleton like this:
90 // folly::Singleton<X> singleton_x([]() { return new X(42, "foo"); });
91 //
92 // The above examples detail a situation where an expensive singleton is loaded
93 // on-demand (thus only if needed). However if there is an expensive singleton
94 // that will likely be needed, and initialization takes a potentially long time,
95 // e.g. while initializing, parsing some files, talking to remote services,
96 // making uses of other singletons, and so on, the initialization of those can
97 // be scheduled up front, or "eagerly".
98 //
99 // In that case the singleton can be declared this way:
100 //
101 // namespace {
102 // auto the_singleton =
103 // folly::Singleton<MyExpensiveService>(/* optional create, destroy args */)
104 // .shouldEagerInit();
105 // }
106 //
107 // This way the singleton's instance is built at program initialization,
108 // if the program opted-in to that feature by calling "doEagerInit" or
109 // "doEagerInitVia" during its startup.
110 //
111 // What if you need to destroy all of your singletons? Say, some of
112 // your singletons manage threads, but you need to fork? Or your unit
113 // test wants to clean up all global state? Then you can call
114 // SingletonVault::singleton()->destroyInstances(), which invokes the
115 // TeardownFunc for each singleton, in the reverse order they were
116 // created. It is your responsibility to ensure your singletons can
117 // handle cases where the singletons they depend on go away, however.
118 // Singletons won't be recreated after destroyInstances call. If you
119 // want to re-enable singleton creation (say after fork was called) you
120 // should call reenableInstances.
121 
122 #pragma once
123 
124 #include <folly/Exception.h>
125 #include <folly/Executor.h>
126 #include <folly/Memory.h>
127 #include <folly/Synchronized.h>
128 #include <folly/detail/Singleton.h>
131 #include <folly/hash/Hash.h>
132 #include <folly/lang/Exception.h>
135 
136 #include <algorithm>
137 #include <atomic>
138 #include <condition_variable>
139 #include <functional>
140 #include <list>
141 #include <memory>
142 #include <mutex>
143 #include <string>
144 #include <thread>
145 #include <typeindex>
146 #include <typeinfo>
147 #include <unordered_map>
148 #include <unordered_set>
149 #include <vector>
150 
151 #include <glog/logging.h>
152 
153 // use this guard to handleSingleton breaking change in 3rd party code
154 #ifndef FOLLY_SINGLETON_TRY_GET
155 #define FOLLY_SINGLETON_TRY_GET
156 #endif
157 
158 namespace folly {
159 
160 // For actual usage, please see the Singleton<T> class at the bottom
161 // of this file; that is what you will actually interact with.
162 
163 // SingletonVault is the class that manages singleton instances. It
164 // is unaware of the underlying types of singletons, and simply
165 // manages lifecycles and invokes CreateFunc and TeardownFunc when
166 // appropriate. In general, you won't need to interact with the
167 // SingletonVault itself.
168 //
169 // A vault goes through a few stages of life:
170 //
171 // 1. Registration phase; singletons can be registered:
172 // a) Strict: no singleton can be created in this stage.
173 // b) Relaxed: singleton can be created (the default vault is Relaxed).
174 // 2. registrationComplete() has been called; singletons can no
175 // longer be registered, but they can be created.
176 // 3. A vault can return to stage 1 when destroyInstances is called.
177 //
178 // In general, you don't need to worry about any of the above; just
179 // ensure registrationComplete() is called near the top of your main()
180 // function, otherwise no singletons can be instantiated.
181 
182 class SingletonVault;
183 
184 namespace detail {
185 
186 // A TypeDescriptor is the unique handle for a given singleton. It is
187 // a combinaiton of the type and of the optional name, and is used as
188 // a key in unordered_maps.
190  public:
191  TypeDescriptor(const std::type_info& ti, const std::type_info& tag_ti)
192  : ti_(ti), tag_ti_(tag_ti) {}
193 
195  : ti_(other.ti_), tag_ti_(other.tag_ti_) {}
196 
198  if (this != &other) {
199  ti_ = other.ti_;
200  tag_ti_ = other.tag_ti_;
201  }
202 
203  return *this;
204  }
205 
206  std::string name() const;
207 
208  friend class TypeDescriptorHasher;
209 
210  bool operator==(const TypeDescriptor& other) const {
211  return ti_ == other.ti_ && tag_ti_ == other.tag_ti_;
212  }
213 
214  private:
215  std::type_index ti_;
216  std::type_index tag_ti_;
217 };
218 
220  public:
221  size_t operator()(const TypeDescriptor& ti) const {
222  return folly::hash::hash_combine(ti.ti_, ti.tag_ti_);
223  }
224 };
225 
227  const TypeDescriptor& type);
228 
230  const TypeDescriptor& type);
231 
233  const TypeDescriptor& type);
234 
236  const TypeDescriptor& type,
237  const void* ptr);
238 
240  const TypeDescriptor& type);
241 
243  const TypeDescriptor& type);
244 
246  const TypeDescriptor& type);
247 
249 
250 [[noreturn]] void singletonThrowNullCreator(const std::type_info& type);
251 
253  const TypeDescriptor& type);
254 
256  // The two stages of life for a vault, as mentioned in the class comment.
257  enum class Type {
258  Running,
259  Quiescing,
260  };
261 
262  Type state{Type::Running};
263  bool registrationComplete{false};
264 
265  // Each singleton in the vault can be in two states: dead
266  // (registered but never created), living (CreateFunc returned an instance).
267 
268  void check(
269  Type expected,
270  const char* msg = "Unexpected singleton state change") const {
271  if (expected != state) {
272  throw_exception<std::logic_error>(msg);
273  }
274  }
275 };
276 
277 // This interface is used by SingletonVault to interact with SingletonHolders.
278 // Having a non-template interface allows SingletonVault to keep a list of all
279 // SingletonHolders.
281  public:
282  explicit SingletonHolderBase(TypeDescriptor typeDesc) : type_(typeDesc) {}
283  virtual ~SingletonHolderBase() = default;
284 
286  return type_;
287  }
288  virtual bool hasLiveInstance() = 0;
289  virtual void createInstance() = 0;
290  virtual bool creationStarted() = 0;
291  virtual void preDestroyInstance(ReadMostlyMainPtrDeleter<>&) = 0;
292  virtual void destroyInstance() = 0;
293 
294  private:
296 };
297 
298 // An actual instance of a singleton, tracking the instance itself,
299 // its state as described above, and the create and teardown
300 // functions.
301 template <typename T>
303  public:
304  typedef std::function<void(T*)> TeardownFunc;
305  typedef std::function<T*(void)> CreateFunc;
306 
307  template <typename Tag, typename VaultTag>
308  inline static SingletonHolder<T>& singleton();
309 
310  inline T* get();
311  inline std::weak_ptr<T> get_weak();
312  inline std::shared_ptr<T> try_get();
313  inline folly::ReadMostlySharedPtr<T> try_get_fast();
314  inline void vivify();
315 
316  void registerSingleton(CreateFunc c, TeardownFunc t);
317  void registerSingletonMock(CreateFunc c, TeardownFunc t);
318  bool hasLiveInstance() override;
319  void createInstance() override;
320  bool creationStarted() override;
321  void preDestroyInstance(ReadMostlyMainPtrDeleter<>&) override;
322  void destroyInstance() override;
323 
324  private:
326 
327  enum class SingletonHolderState {
328  NotRegistered,
329  Dead,
330  Living,
331  };
332 
334 
335  // mutex protects the entire entry during construction/destruction
337 
338  // State of the singleton entry. If state is Living, instance_ptr and
339  // instance_weak can be safely accessed w/o synchronization.
340  std::atomic<SingletonHolderState> state_{SingletonHolderState::NotRegistered};
341 
342  // the thread creating the singleton (only valid while creating an object)
343  std::atomic<std::thread::id> creating_thread_{};
344 
345  // The singleton itself and related functions.
346 
347  // holds a ReadMostlyMainPtr to singleton instance, set when state is changed
348  // from Dead to Living. Reset when state is changed from Living to Dead.
350  // used to release all ReadMostlyMainPtrs at once
352  // weak_ptr to the singleton instance, set when state is changed from Dead
353  // to Living. We never write to this object after initialization, so it is
354  // safe to read it from different threads w/o synchronization if we know
355  // that state is set to Living
356  std::weak_ptr<T> instance_weak_;
357  // Fast equivalent of instance_weak_
359  // Time we wait on destroy_baton after releasing Singleton shared_ptr.
360  std::shared_ptr<folly::Baton<>> destroy_baton_;
361  T* instance_ptr_ = nullptr;
362  CreateFunc create_ = nullptr;
363  TeardownFunc teardown_ = nullptr;
364 
365  std::shared_ptr<std::atomic<bool>> print_destructor_stack_trace_;
366 
367  SingletonHolder(const SingletonHolder&) = delete;
368  SingletonHolder& operator=(const SingletonHolder&) = delete;
370  SingletonHolder(SingletonHolder&&) = delete;
371 };
372 
373 } // namespace detail
374 
376  public:
377  enum class Type {
378  Strict, // Singletons can't be created before registrationComplete()
379  Relaxed, // Singletons can be created before registrationComplete()
380  };
381 
393  struct ScopedExpunger {
395  explicit ScopedExpunger(SingletonVault* v) : vault(v) {
396  expunge();
397  }
399  expunge();
400  }
401  void expunge() {
402  vault->destroyInstances();
403  vault->reenableInstances();
404  }
405  };
406 
407  static Type defaultVaultType();
408 
409  explicit SingletonVault(Type type = defaultVaultType()) : type_(type) {}
410 
411  // Destructor is only called by unit tests to check destroyInstances.
412  ~SingletonVault();
413 
414  typedef std::function<void(void*)> TeardownFunc;
415  typedef std::function<void*(void)> CreateFunc;
416 
417  // Ensure that Singleton has not been registered previously and that
418  // registration is not complete. If validations succeeds,
419  // register a singleton of a given type with the create and teardown
420  // functions.
421  void registerSingleton(detail::SingletonHolderBase* entry);
422 
428  void addEagerInitSingleton(detail::SingletonHolderBase* entry);
429 
430  // Mark registration is complete; no more singletons can be
431  // registered at this point.
432  void registrationComplete();
433 
440  void doEagerInit();
441 
460  void doEagerInitVia(Executor& exe, folly::Baton<>* done = nullptr);
461 
462  // Destroy all singletons; when complete, the vault can't create
463  // singletons once again until reenableInstances() is called.
464  void destroyInstances();
465 
466  // Enable re-creating singletons after destroyInstances() was called.
467  void reenableInstances();
468 
469  // For testing; how many registered and living singletons we have.
470  size_t registeredSingletonCount() const {
471  return singletons_.rlock()->size();
472  }
473 
478  bool eagerInitComplete() const;
479 
480  size_t livingSingletonCount() const {
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  }
492 
493  // A well-known vault; you can actually have others, but this is the
494  // default.
496  return singleton<>();
497  }
498 
499  // Gets singleton vault for any Tag. Non-default tag should be used in unit
500  // tests only.
501  template <typename VaultTag = detail::DefaultTag>
503  /* library-local */ static auto vault =
504  detail::createGlobal<SingletonVault, VaultTag>();
505  return vault;
506  }
507 
508  typedef std::string (*StackTraceGetterPtr)();
509 
510  static std::atomic<StackTraceGetterPtr>& stackTraceGetter() {
511  /* library-local */ static auto stackTraceGetterPtr = detail::
512  createGlobal<std::atomic<StackTraceGetterPtr>, SingletonVault>();
513  return *stackTraceGetterPtr;
514  }
515 
516  void setType(Type type) {
517  type_ = type;
518  }
519 
520  private:
521  template <typename T>
522  friend struct detail::SingletonHolder;
523 
524  // This method only matters if registrationComplete() is never called.
525  // Otherwise destroyInstances is scheduled to be executed atexit.
526  //
527  // Initializes static object, which calls destroyInstances on destruction.
528  // Used to have better deletion ordering with singleton not managed by
529  // folly::Singleton. The desruction will happen in the following order:
530  // 1. Singletons, not managed by folly::Singleton, which were created after
531  // any of the singletons managed by folly::Singleton was requested.
532  // 2. All singletons managed by folly::Singleton
533  // 3. Singletons, not managed by folly::Singleton, which were created before
534  // any of the singletons managed by folly::Singleton was requested.
535  static void scheduleDestroyInstances();
536 
537  typedef std::unordered_map<
542 
543  // Use SharedMutexSuppressTSAN to suppress noisy lock inversions when building
544  // with TSAN. If TSAN is not enabled, SharedMutexSuppressTSAN is equivalent
545  // to a normal SharedMutex.
547  Synchronized<
548  std::unordered_set<detail::SingletonHolderBase*>,
553 
554  // Using SharedMutexReadPriority is important here, because we want to make
555  // sure we don't block nested singleton creation happening concurrently with
556  // destroyInstances().
558 
560 };
561 
562 // This is the wrapper class that most users actually interact with.
563 // It allows for simple access to registering and instantiating
564 // singletons. Create instances of this class in the global scope of
565 // type Singleton<T> to register your singleton for later access via
566 // Singleton<T>::try_get().
567 template <
568  typename T,
569  typename Tag = detail::DefaultTag,
570  typename VaultTag = detail::DefaultTag /* for testing */>
571 class Singleton {
572  public:
573  typedef std::function<T*(void)> CreateFunc;
574  typedef std::function<void(T*)> TeardownFunc;
575 
576  // Generally your program life cycle should be fine with calling
577  // get() repeatedly rather than saving the reference, and then not
578  // call get() during process shutdown.
579  [[deprecated("Replaced by try_get")]] static T* get() {
580  return getEntry().get();
581  }
582 
583  // If, however, you do need to hold a reference to the specific
584  // singleton, you can try to do so with a weak_ptr. Avoid this when
585  // possible but the inability to lock the weak pointer can be a
586  // signal that the vault has been destroyed.
587  [[deprecated("Replaced by try_get")]] static std::weak_ptr<T> get_weak() {
588  return getEntry().get_weak();
589  }
590 
591  // Preferred alternative to get_weak, it returns shared_ptr that can be
592  // stored; a singleton won't be destroyed unless shared_ptr is destroyed.
593  // Avoid holding these shared_ptrs beyond the scope of a function;
594  // don't put them in member variables, always use try_get() instead
595  //
596  // try_get() can return nullptr if the singleton was destroyed, caller is
597  // responsible for handling nullptr return
598  static std::shared_ptr<T> try_get() {
599  return getEntry().try_get();
600  }
601 
603  return getEntry().try_get_fast();
604  }
605 
606  // Quickly ensure the instance exists.
607  static void vivify() {
608  getEntry().vivify();
609  }
610 
611  explicit Singleton(
612  std::nullptr_t /* _ */ = nullptr,
613  typename Singleton::TeardownFunc t = nullptr)
614  : Singleton([]() { return new T; }, std::move(t)) {}
615 
616  explicit Singleton(
617  typename Singleton::CreateFunc c,
618  typename Singleton::TeardownFunc t = nullptr) {
619  if (c == nullptr) {
621  }
622 
623  auto vault = SingletonVault::singleton<VaultTag>();
624  getEntry().registerSingleton(std::move(c), getTeardownFunc(std::move(t)));
625  vault->registerSingleton(&getEntry());
626  }
627 
645  auto vault = SingletonVault::singleton<VaultTag>();
646  vault->addEagerInitSingleton(&getEntry());
647  return *this;
648  }
649 
660  static void make_mock(
661  std::nullptr_t /* c */ = nullptr,
662  typename Singleton<T>::TeardownFunc t = nullptr) {
663  make_mock([]() { return new T; }, t);
664  }
665 
666  static void make_mock(
667  CreateFunc c,
668  typename Singleton<T>::TeardownFunc t = nullptr) {
669  if (c == nullptr) {
671  }
672 
673  auto& entry = getEntry();
674 
675  entry.registerSingletonMock(c, getTeardownFunc(t));
676  }
677 
678  private:
680  return detail::SingletonHolder<T>::template singleton<Tag, VaultTag>();
681  }
682 
683  // Construct TeardownFunc.
685  TeardownFunc t) {
686  if (t == nullptr) {
687  return [](T* v) { delete v; };
688  } else {
689  return t;
690  }
691  }
692 };
693 
694 template <typename T, typename Tag = detail::DefaultTag>
696  public:
697  using CreateFunc = std::function<T*()>;
698 
699  LeakySingleton() : LeakySingleton([] { return new T(); }) {}
700 
701  explicit LeakySingleton(CreateFunc createFunc) {
702  auto& entry = entryInstance();
703  if (entry.state != State::NotRegistered) {
705  }
706  entry.createFunc = createFunc;
707  entry.state = State::Dead;
708  }
709 
710  static T& get() {
711  return instance();
712  }
713 
714  static void make_mock(std::nullptr_t /* c */ = nullptr) {
715  make_mock([]() { return new T; });
716  }
717 
718  static void make_mock(CreateFunc createFunc) {
719  if (createFunc == nullptr) {
721  }
722 
723  auto& entry = entryInstance();
724  if (entry.ptr) {
725  // Make sure existing pointer doesn't get reported as a leak by LSAN.
726  entry.leakedPtrs.push_back(std::exchange(entry.ptr, nullptr));
727  }
728  entry.createFunc = createFunc;
729  entry.state = State::Dead;
730  }
731 
732  private:
733  enum class State { NotRegistered, Dead, Living };
734 
735  struct Entry {
736  Entry() {}
737  Entry(const Entry&) = delete;
738  Entry& operator=(const Entry&) = delete;
739 
740  std::atomic<State> state{State::NotRegistered};
741  T* ptr{nullptr};
744  detail::TypeDescriptor type_{typeid(T), typeid(Tag)};
745  std::list<T*> leakedPtrs;
746  };
747 
748  static Entry& entryInstance() {
749  /* library-local */ static auto entry = detail::createGlobal<Entry, Tag>();
750  return *entry;
751  }
752 
753  static T& instance() {
754  auto& entry = entryInstance();
755  if (UNLIKELY(entry.state != State::Living)) {
756  createInstance();
757  }
758 
759  return *entry.ptr;
760  }
761 
762  static void createInstance() {
763  auto& entry = entryInstance();
764 
765  std::lock_guard<std::mutex> lg(entry.mutex);
766  if (entry.state == State::Living) {
767  return;
768  }
769 
770  if (entry.state == State::NotRegistered) {
772  }
773 
774  entry.ptr = entry.createFunc();
775  entry.state = State::Living;
776  }
777 };
778 } // namespace folly
779 
780 #include <folly/Singleton-inl.h>
void * ptr
SingletonHolderBase(TypeDescriptor typeDesc)
Definition: Singleton.h:282
size_t livingSingletonCount() const
Definition: Singleton.h:480
bool operator==(const TypeDescriptor &other) const
Definition: Singleton.h:210
static T & instance()
Definition: Singleton.h:753
std::function< void(T *)> TeardownFunc
Definition: Singleton.h:574
TypeDescriptor & operator=(const TypeDescriptor &other)
Definition: Singleton.h:197
static detail::SingletonHolder< T >::TeardownFunc getTeardownFunc(TeardownFunc t)
Definition: Singleton.h:684
auto v
std::unordered_map< detail::TypeDescriptor, detail::SingletonHolderBase *, detail::TypeDescriptorHasher > SingletonMap
Definition: Singleton.h:541
void singletonThrowNullCreator(const std::type_info &type)
Definition: Singleton.cpp:174
static SingletonVault * singleton()
Definition: Singleton.h:495
static SingletonVault * singleton()
Definition: Singleton.h:502
static Singleton< ShutdownSocketSet, PrivateTag > singleton
std::function< void(void *)> TeardownFunc
Definition: Singleton.h:414
static void make_mock(std::nullptr_t=nullptr, typename Singleton< T >::TeardownFunc t=nullptr)
Definition: Singleton.h:660
PskType type
LeakySingleton(CreateFunc createFunc)
Definition: Singleton.h:701
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static void make_mock(CreateFunc createFunc)
Definition: Singleton.h:718
void singletonWarnCreateUnregisteredAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:133
SingletonVault(Type type=defaultVaultType())
Definition: Singleton.h:409
void singletonWarnCreateCircularDependencyAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:128
void check(Type expected, const char *msg="Unexpected singleton state change") const
Definition: Singleton.h:268
size_t operator()(const TypeDescriptor &ti) const
Definition: Singleton.h:221
void singletonWarnLeakyInstantiatingNotRegisteredAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:99
folly::std T
std::function< T *(void)> CreateFunc
Definition: Singleton.h:305
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
static void vivify()
Definition: Singleton.h:607
Synchronized< std::unordered_set< detail::SingletonHolderBase * >, SharedMutexSuppressTSAN > eagerInitSingletons_
Definition: Singleton.h:550
folly::ReadMostlyMainPtr< T > instance_
Definition: Singleton.h:349
static std::atomic< StackTraceGetterPtr > & stackTraceGetter()
Definition: Singleton.h:510
static void make_mock(CreateFunc c, typename Singleton< T >::TeardownFunc t=nullptr)
Definition: Singleton.h:666
void singletonThrowGetInvokedAfterDestruction(const TypeDescriptor &type)
Definition: Singleton.cpp:181
Singleton(std::nullptr_t=nullptr, typename Singleton::TeardownFunc t=nullptr)
Definition: Singleton.h:611
void singletonWarnRegisterMockEarlyAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:109
static Entry & entryInstance()
Definition: Singleton.h:748
Type type_
Definition: JSONSchema.cpp:208
size_t hash_combine(const T &t, const Ts &...ts) noexcept(noexcept(hash_combine_generic(StdHasher{}, t, ts...)))
Definition: Hash.h:669
std::shared_ptr< folly::Baton<> > destroy_baton_
Definition: Singleton.h:360
void singletonWarnDestroyInstanceLeak(const TypeDescriptor &type, const void *ptr)
Definition: Singleton.cpp:115
static void createInstance()
Definition: Singleton.h:762
static detail::SingletonHolder< T > & getEntry()
Definition: Singleton.h:679
folly::ReadMostlyWeakPtr< T > instance_weak_fast_
Definition: Singleton.h:358
TypeDescriptor(const TypeDescriptor &other)
Definition: Singleton.h:194
size_t registeredSingletonCount() const
Definition: Singleton.h:470
static void make_mock(std::nullptr_t=nullptr)
Definition: Singleton.h:714
void singletonWarnLeakyDoubleRegistrationAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:88
void setType(Type type)
Definition: Singleton.h:516
std::function< void *(void)> CreateFunc
Definition: Singleton.h:415
static std::shared_ptr< T > try_get()
Definition: Singleton.h:598
std::string name() const
Definition: Singleton.cpp:67
T exchange(T &obj, U &&new_value)
Definition: Utility.h:120
TypeDescriptor(const std::type_info &ti, const std::type_info &tag_ti)
Definition: Singleton.h:191
std::mutex mutex
const char * string
Definition: Conv.cpp:212
std::weak_ptr< T > instance_weak_
Definition: Singleton.h:356
void singletonWarnCreateBeforeRegistrationCompleteAndAbort(const TypeDescriptor &type)
Definition: Singleton.cpp:143
TypeDescriptor type() const
Definition: Singleton.h:285
InlineExecutor exe
Definition: Benchmark.cpp:337
void singletonPrintDestructionStackTrace(const TypeDescriptor &type)
Definition: Singleton.cpp:159
std::shared_ptr< std::atomic< bool > > print_destructor_stack_trace_
Definition: Singleton.h:365
static folly::ReadMostlySharedPtr< T > try_get_fast()
Definition: Singleton.h:602
static std::weak_ptr< T > get_weak()
Definition: Singleton.h:587
std::function< T *()> CreateFunc
Definition: Singleton.h:697
#define UNLIKELY(x)
Definition: Likely.h:48
std::function< T *(void)> CreateFunc
Definition: Singleton.h:573
char c
folly::ReadMostlySharedPtr< T > instance_copy_
Definition: Singleton.h:351
Singleton(typename Singleton::CreateFunc c, typename Singleton::TeardownFunc t=nullptr)
Definition: Singleton.h:616
std::function< void(T *)> TeardownFunc
Definition: Singleton.h:304
Synchronized< std::vector< detail::TypeDescriptor >, SharedMutexSuppressTSAN > creationOrder_
Definition: Singleton.h:552
std::list< T * > leakedPtrs
Definition: Singleton.h:745
Singleton & shouldEagerInit()
Definition: Singleton.h:644
state
Definition: http_parser.c:272
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_
Definition: Singleton.h:557
Synchronized< SingletonMap, SharedMutexSuppressTSAN > singletons_
Definition: Singleton.h:546