Commit e5e3fde0 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by dcsommer

Schedule destroyInstances only when first singleton is created

Summary:
Right now destroyInstances is scheduled when SingletonVault is requested. This may change singleton destruction order (folly::Singleton-managed vs unmanaged singletons) when new singleton is registered with folly::Singleton (no matter if it is even used).
This diff changes it to be more stable.

Test Plan: servicerouter unittests

Reviewed By: chip@fb.com

Subscribers: njormrod, mshneer

FB internal diff: D1615213

Tasks: 5353022
parent ca4b4d09
......@@ -73,16 +73,22 @@ void SingletonVault::reenableInstances() {
SingletonVault* SingletonVault::singleton() {
static SingletonVault* vault = new SingletonVault();
return vault;
}
void SingletonVault::scheduleDestroyInstances() {
class SingletonVaultDestructor {
public:
~SingletonVaultDestructor() {
SingletonVault::singleton()->destroyInstances();
}
};
static SingletonVaultDestructor singletonVaultDestructor;
return vault;
// Here we intialize a singleton, which calls destroyInstances in its
// destructor. Because of singleton destruction order - it will be destroyed
// before all the singletons, which were initialized before it and after all
// the singletons initialized after it.
static SingletonVaultDestructor singletonVaultDestructor;
}
}
......@@ -329,6 +329,16 @@ class SingletonVault {
SingletonEntry(SingletonEntry&&) = delete;
};
// Initializes static object, which calls destroyInstances on destruction.
// Used to have better deletion ordering with singleton not managed by
// folly::Singleton. The desruction will happen in the following order:
// 1. Singletons, not managed by folly::Singleton, which were created after
// any of the singletons managed by folly::Singleton was requested.
// 2. All singletons managed by folly::Singleton
// 3. Singletons, not managed by folly::Singleton, which were created before
// any of the singletons managed by folly::Singleton was requested.
static void scheduleDestroyInstances();
SingletonEntry* get_entry(detail::TypeDescriptor type) {
RWSpinLock::ReadHolder rh(&mutex_);
......@@ -375,6 +385,13 @@ class SingletonVault {
entry_lock.unlock();
// Can't use make_shared -- no support for a custom deleter, sadly.
auto instance = std::shared_ptr<void>(entry->create(), entry->teardown);
// We should schedule destroyInstances() only after the singleton was
// created. This will ensure it will be destroyed before singletons,
// not managed by folly::Singleton, which were initialized in its
// constructor
scheduleDestroyInstances();
entry_lock.lock();
CHECK(entry->state == SingletonEntryState::BeingBorn);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment