Register singleton's destruction using std::atexit
authorSergey Makarenko <smakarenko@fb.com>
Fri, 12 Jan 2018 21:42:05 +0000 (13:42 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Fri, 12 Jan 2018 22:05:07 +0000 (14:05 -0800)
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

folly/Singleton.cpp

index f02cd3f613f3f4013553f82a87b194228f52cb93..0800ac65d4bed8b20f31968d466db9aac0a6b32e 100644 (file)
@@ -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<void, void>::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