From: Sergey Makarenko Date: Fri, 12 Jan 2018 21:42:05 +0000 (-0800) Subject: Register singleton's destruction using std::atexit X-Git-Tag: v2018.01.15.00~9 X-Git-Url: http://demsky.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=3f4a8ae005738662fbbca4a85c959df2bf0d059b Register singleton's destruction using std::atexit Summary: scheduleDestroyInstances function is called from createInstance function when new instance of specific singleton type is created thus marking a point in static objects order when all singltons will be destructed. This does not work well for situations when singleton is loaded as part of python extension which is a shared object. In this case static objects of this shared object would be constructed first and singleton from this extension will be created after that. Since destruction order is reversed and all singletons will be destructed together, static objects of python extension will be destroyed before singleton from this extension. Which leads to heap-after-free ASAN exceptions. In other words, lifetime of all folly singletons is aligned to the lifetime of the first created folly singleton. Using std::atexit to register singleton's destruction from singleton constructor will align lifetime of singletons to the most recent singleton which matters for python extensions and does not matter for other use cases. Reviewed By: andriigrynenko Differential Revision: D6705644 fbshipit-source-id: 5c933886ceae649e3c75f8e7e7936d5a7ed04539 --- diff --git a/folly/Singleton.cpp b/folly/Singleton.cpp index f02cd3f6..0800ac65 100644 --- a/folly/Singleton.cpp +++ b/folly/Singleton.cpp @@ -374,19 +374,7 @@ void SingletonVault::scheduleDestroyInstances() { // Add a dependency on folly::ThreadLocal to make sure all its static // singletons are initalized first. threadlocal_detail::StaticMeta::instance(); - - class SingletonVaultDestructor { - public: - ~SingletonVaultDestructor() { - SingletonVault::singleton()->destroyInstances(); - } - }; - - // 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; + std::atexit([] { SingletonVault::singleton()->destroyInstances(); }); } } // namespace folly