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