1 // Copyright 2011 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_AT_EXIT_H_ 6 #define BASE_AT_EXIT_H_ 7 8 #include "base/base_export.h" 9 #include "base/containers/stack.h" 10 #include "base/dcheck_is_on.h" 11 #include "base/functional/callback.h" 12 #include "base/memory/raw_ptr.h" 13 #include "base/synchronization/lock.h" 14 #include "base/thread_annotations.h" 15 16 namespace base { 17 18 // This class provides a facility similar to the CRT atexit(), except that 19 // we control when the callbacks are executed. Under Windows for a DLL they 20 // happen at a really bad time and under the loader lock. This facility is 21 // mostly used by base::Singleton. 22 // 23 // The usage is simple. Early in the main() or WinMain() scope create an 24 // AtExitManager object on the stack: 25 // int main(...) { 26 // base::AtExitManager exit_manager; 27 // 28 // } 29 // When the exit_manager object goes out of scope, all the registered 30 // callbacks and singleton destructors will be called. 31 32 class BASE_EXPORT AtExitManager { 33 public: 34 typedef void (*AtExitCallbackType)(void*); 35 36 AtExitManager(); 37 AtExitManager(const AtExitManager&) = delete; 38 AtExitManager& operator=(const AtExitManager&) = delete; 39 40 // The dtor calls all the registered callbacks. Do not try to register more 41 // callbacks after this point. 42 ~AtExitManager(); 43 44 // Registers the specified function to be called at exit. The prototype of 45 // the callback function is void func(void*). 46 static void RegisterCallback(AtExitCallbackType func, void* param); 47 48 // Registers the specified task to be called at exit. 49 static void RegisterTask(base::OnceClosure task); 50 51 // Calls the functions registered with RegisterCallback in LIFO order. It 52 // is possible to register new callbacks after calling this function. 53 static void ProcessCallbacksNow(); 54 55 // Disable all registered at-exit callbacks. This is used only in a single- 56 // process mode. 57 static void DisableAllAtExitManagers(); 58 59 protected: 60 // This constructor will allow this instance of AtExitManager to be created 61 // even if one already exists. This should only be used for testing! 62 // AtExitManagers are kept on a global stack, and it will be removed during 63 // destruction. This allows you to shadow another AtExitManager. 64 explicit AtExitManager(bool shadow); 65 66 private: 67 base::Lock lock_; 68 69 base::stack<base::OnceClosure> stack_ GUARDED_BY(lock_); 70 71 #if DCHECK_IS_ON() 72 bool processing_callbacks_ GUARDED_BY(lock_) = false; 73 #endif 74 75 // Stack of managers to allow shadowing. 76 const raw_ptr<AtExitManager, DanglingUntriaged> next_manager_; 77 }; 78 79 #if defined(UNIT_TEST) 80 class ShadowingAtExitManager : public AtExitManager { 81 public: ShadowingAtExitManager()82 ShadowingAtExitManager() : AtExitManager(true) {} 83 }; 84 #endif // defined(UNIT_TEST) 85 86 } // namespace base 87 88 #endif // BASE_AT_EXIT_H_ 89