[email protected] | a502bbe7 | 2011-01-07 18:06:45 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 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_ | ||||
[email protected] | 32b76ef | 2010-07-26 23:08:24 | [diff] [blame] | 7 | #pragma once |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 8 | |
9 | #include <stack> | ||||
10 | |||||
[email protected] | 0bea725 | 2011-08-05 15:34:00 | [diff] [blame] | 11 | #include "base/base_export.h" |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 12 | #include "base/basictypes.h" |
[email protected] | 762de91 | 2011-09-06 23:14:47 | [diff] [blame] | 13 | #include "base/callback.h" |
[email protected] | 20305ec | 2011-01-21 04:55:52 | [diff] [blame] | 14 | #include "base/synchronization/lock.h" |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 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; | ||||
[email protected] | 52a261f | 2009-03-03 15:01:12 | [diff] [blame] | 27 | // |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 28 | // } |
29 | // When the exit_manager object goes out of scope, all the registered | ||||
30 | // callbacks and singleton destructors will be called. | ||||
31 | |||||
[email protected] | 0bea725 | 2011-08-05 15:34:00 | [diff] [blame] | 32 | class BASE_EXPORT AtExitManager { |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 33 | public: |
[email protected] | 9795ec1 | 2008-09-08 09:06:51 | [diff] [blame] | 34 | typedef void (*AtExitCallbackType)(void*); |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 35 | |
36 | AtExitManager(); | ||||
37 | |||||
38 | // The dtor calls all the registered callbacks. Do not try to register more | ||||
39 | // callbacks after this point. | ||||
40 | ~AtExitManager(); | ||||
41 | |||||
42 | // Registers the specified function to be called at exit. The prototype of | ||||
[email protected] | 762de91 | 2011-09-06 23:14:47 | [diff] [blame] | 43 | // the callback function is void func(void*). |
[email protected] | 9795ec1 | 2008-09-08 09:06:51 | [diff] [blame] | 44 | static void RegisterCallback(AtExitCallbackType func, void* param); |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 45 | |
[email protected] | 762de91 | 2011-09-06 23:14:47 | [diff] [blame] | 46 | // Registers the specified task to be called at exit. |
47 | static void RegisterTask(base::Closure task); | ||||
48 | |||||
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 49 | // Calls the functions registered with RegisterCallback in LIFO order. It |
50 | // is possible to register new callbacks after calling this function. | ||||
51 | static void ProcessCallbacksNow(); | ||||
52 | |||||
[email protected] | a502bbe7 | 2011-01-07 18:06:45 | [diff] [blame] | 53 | protected: |
54 | // This constructor will allow this instance of AtExitManager to be created | ||||
55 | // even if one already exists. This should only be used for testing! | ||||
56 | // AtExitManagers are kept on a global stack, and it will be removed during | ||||
57 | // destruction. This allows you to shadow another AtExitManager. | ||||
58 | explicit AtExitManager(bool shadow); | ||||
59 | |||||
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 60 | private: |
[email protected] | 20305ec | 2011-01-21 04:55:52 | [diff] [blame] | 61 | base::Lock lock_; |
[email protected] | 762de91 | 2011-09-06 23:14:47 | [diff] [blame] | 62 | std::stack<base::Closure> stack_; |
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 63 | AtExitManager* next_manager_; // Stack of managers to allow shadowing. |
64 | |||||
65 | DISALLOW_COPY_AND_ASSIGN(AtExitManager); | ||||
66 | }; | ||||
67 | |||||
[email protected] | 4ea927b | 2009-11-19 09:11:39 | [diff] [blame] | 68 | #if defined(UNIT_TEST) |
69 | class ShadowingAtExitManager : public AtExitManager { | ||||
70 | public: | ||||
71 | ShadowingAtExitManager() : AtExitManager(true) {} | ||||
72 | }; | ||||
73 | #endif // defined(UNIT_TEST) | ||||
74 | |||||
[email protected] | b2e9729 | 2008-09-02 18:20:34 | [diff] [blame] | 75 | } // namespace base |
76 | |||||
77 | #endif // BASE_AT_EXIT_H_ |