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