22 template <
typename Tag,
typename VaultTag>
25 createGlobal<SingletonHolder<T>, std::pair<Tag, VaultTag>>([]() {
27 {
typeid(
T),
typeid(
Tag)}, *SingletonVault::singleton<VaultTag>());
37 std::lock_guard<std::mutex> entry_lock(
mutex_);
39 if (state_ != SingletonHolderState::NotRegistered) {
65 state_ = SingletonHolderState::Dead;
70 if (state_ == SingletonHolderState::NotRegistered) {
73 if (state_ == SingletonHolderState::Living) {
78 auto creationOrder = vault_.creationOrder_.wlock();
80 auto it = std::find(creationOrder->begin(), creationOrder->end(),
type());
81 if (it != creationOrder->end()) {
82 creationOrder->erase(it);
86 std::lock_guard<std::mutex> entry_lock(
mutex_);
95 state_.load(std::memory_order_acquire) ==
96 SingletonHolderState::Living)) {
101 if (instance_weak_.expired()) {
105 return instance_ptr_;
108 template <
typename T>
111 state_.load(std::memory_order_acquire) !=
112 SingletonHolderState::Living)) {
116 return instance_weak_;
119 template <
typename T>
122 state_.load(std::memory_order_acquire) !=
123 SingletonHolderState::Living)) {
127 return instance_weak_.lock();
130 template <
typename T>
133 state_.load(std::memory_order_acquire) !=
134 SingletonHolderState::Living)) {
138 return instance_weak_fast_.lock();
141 template <
typename T>
144 state_.load(std::memory_order_relaxed) !=
145 SingletonHolderState::Living)) {
150 template <
typename T>
152 return !instance_weak_.expired();
155 template <
typename T>
158 instance_copy_ = instance_;
162 template <
typename T>
164 state_ = SingletonHolderState::Dead;
166 instance_copy_.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) {
172 teardown_(instance_ptr_);
174 print_destructor_stack_trace_->store(
true);
180 template <
typename T>
186 template <
typename T>
195 if (
creating_thread_.load(std::memory_order_acquire) != std::thread::id()) {
202 template <
typename T>
205 std::this_thread::get_id()) {
209 std::lock_guard<std::mutex> entry_lock(
mutex_);
213 if (
state_.load(std::memory_order_acquire) ==
229 creating_thread_.store(std::this_thread::get_id(), std::memory_order_release);
233 !
state->registrationComplete) {
240 auto destroy_baton = std::make_shared<folly::Baton<>>();
241 auto print_destructor_stack_trace =
242 std::make_shared<std::atomic<bool>>(
false);
245 std::shared_ptr<T> instance(
247 [destroy_baton, print_destructor_stack_trace, type =
type()](
T*)
mutable {
248 destroy_baton->post();
249 if (print_destructor_stack_trace->load()) {
folly::ReadMostlySharedPtr< T > try_get_fast()
void preDestroyInstance(ReadMostlyMainPtrDeleter<> &) override
constexpr detail::Map< Move > move
void singletonWarnCreateUnregisteredAndAbort(const TypeDescriptor &type)
void singletonWarnCreateCircularDependencyAndAbort(const TypeDescriptor &type)
std::function< T *(void)> CreateFunc
—— Concurrent Priority Queue Implementation ——
void registerSingleton(CreateFunc c, TeardownFunc t)
static SingletonHolder< T > & singleton()
std::shared_ptr< T > try_get()
folly::ReadMostlyMainPtr< T > instance_
std::weak_ptr< T > get_weak()
void createInstance() override
void singletonThrowGetInvokedAfterDestruction(const TypeDescriptor &type)
void registerSingletonMock(CreateFunc c, TeardownFunc t)
void singletonWarnRegisterMockEarlyAndAbort(const TypeDescriptor &type)
void singletonWarnDoubleRegistrationAndAbort(const TypeDescriptor &type)
std::shared_ptr< folly::Baton<> > destroy_baton_
void singletonWarnDestroyInstanceLeak(const TypeDescriptor &type, const void *ptr)
folly::ReadMostlyWeakPtr< T > instance_weak_fast_
std::atomic< std::thread::id > creating_thread_
void add(ReadMostlyMainPtr< T, RefCount > ptr) noexcept
static void scheduleDestroyInstances()
bool creationStarted() override
bool hasLiveInstance() override
std::weak_ptr< T > instance_weak_
void singletonWarnCreateBeforeRegistrationCompleteAndAbort(const TypeDescriptor &type)
std::atomic< SingletonHolderState > state_
TypeDescriptor type() const
void singletonPrintDestructionStackTrace(const TypeDescriptor &type)
std::shared_ptr< std::atomic< bool > > print_destructor_stack_trace_
SingletonHolder(TypeDescriptor type, SingletonVault &vault)
void destroyInstance() override
std::function< void(T *)> TeardownFunc
Synchronized< std::vector< detail::TypeDescriptor >, SharedMutexSuppressTSAN > creationOrder_
Synchronized< detail::SingletonVaultState, SharedMutexReadPriority > state_