2 * Copyright 2014 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <folly/experimental/Singleton.h>
23 SingletonVault::~SingletonVault() { destroyInstances(); }
25 void SingletonVault::destroyInstances() {
26 RWSpinLock::WriteHolder state_wh(&stateMutex_);
28 if (state_ == SingletonVaultState::Quiescing) {
31 state_ = SingletonVaultState::Quiescing;
33 RWSpinLock::ReadHolder state_rh(std::move(state_wh));
36 RWSpinLock::ReadHolder rh(&mutex_);
38 CHECK_GE(singletons_.size(), creation_order_.size());
40 for (auto type_iter = creation_order_.rbegin();
41 type_iter != creation_order_.rend();
43 auto type = *type_iter;
44 auto it = singletons_.find(type);
45 CHECK(it != singletons_.end());
46 auto& entry = it->second;
47 std::lock_guard<std::mutex> entry_guard(entry->mutex);
48 if (entry->instance.use_count() > 1) {
49 LOG(ERROR) << "Singleton of type " << type.name() << " has a living "
50 << "reference at destroyInstances time; beware! Raw pointer "
51 << "is " << entry->instance.get() << " with use_count of "
52 << entry->instance.use_count();
54 entry->instance.reset();
55 entry->state = SingletonEntryState::Dead;
56 entry->state_condvar.notify_all();
61 RWSpinLock::WriteHolder wh(&mutex_);
62 creation_order_.clear();
66 void SingletonVault::reenableInstances() {
67 RWSpinLock::WriteHolder state_wh(&stateMutex_);
69 stateCheck(SingletonVaultState::Quiescing);
71 state_ = SingletonVaultState::Running;
74 SingletonVault* SingletonVault::singleton() {
75 static SingletonVault* vault = new SingletonVault();
77 class SingletonVaultDestructor {
79 ~SingletonVaultDestructor() {
80 SingletonVault::singleton()->destroyInstances();
83 static SingletonVaultDestructor singletonVaultDestructor;