blob: 6bf3f50350ec7f76d2f0193aeafb3ee84975517a [file] [log] [blame]
scottbyer@chromium.org189aa712012-07-26 05:36:33 +09001// Copyright (c) 2011 The Chromium Authors. All rights reserved.
mmentovai@google.comaa13be62008-09-03 03:20:34 +09002// 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
darin@chromium.orge585bed2011-08-06 00:34:00 +090010#include "base/base_export.h"
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090011#include "base/callback.h"
avia6a6a682015-12-27 07:15:14 +090012#include "base/macros.h"
brettw@chromium.orgabe477a2011-01-21 13:55:52 +090013#include "base/synchronization/lock.h"
mmentovai@google.comaa13be62008-09-03 03:20:34 +090014
15namespace 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;
maruel@chromium.org8fe7adc2009-03-04 00:01:12 +090026//
mmentovai@google.comaa13be62008-09-03 03:20:34 +090027// }
28// When the exit_manager object goes out of scope, all the registered
29// callbacks and singleton destructors will be called.
30
darin@chromium.orge585bed2011-08-06 00:34:00 +090031class BASE_EXPORT AtExitManager {
mmentovai@google.comaa13be62008-09-03 03:20:34 +090032 public:
deanm@google.comf6299e72008-09-08 18:06:51 +090033 typedef void (*AtExitCallbackType)(void*);
mmentovai@google.comaa13be62008-09-03 03:20:34 +090034
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
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090042 // the callback function is void func(void*).
deanm@google.comf6299e72008-09-08 18:06:51 +090043 static void RegisterCallback(AtExitCallbackType func, void* param);
mmentovai@google.comaa13be62008-09-03 03:20:34 +090044
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090045 // Registers the specified task to be called at exit.
46 static void RegisterTask(base::Closure task);
47
mmentovai@google.comaa13be62008-09-03 03:20:34 +090048 // 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
harakendf522bd2017-01-12 16:14:04 +090052 // Disable all registered at-exit callbacks. This is used only in a single-
53 // process mode.
54 static void DisableAllAtExitManagers();
55
erg@google.comd5fffd42011-01-08 03:06:45 +090056 protected:
57 // This constructor will allow this instance of AtExitManager to be created
58 // even if one already exists. This should only be used for testing!
59 // AtExitManagers are kept on a global stack, and it will be removed during
60 // destruction. This allows you to shadow another AtExitManager.
61 explicit AtExitManager(bool shadow);
62
mmentovai@google.comaa13be62008-09-03 03:20:34 +090063 private:
brettw@chromium.orgabe477a2011-01-21 13:55:52 +090064 base::Lock lock_;
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090065 std::stack<base::Closure> stack_;
amistry11fd6402016-02-10 11:18:33 +090066 bool processing_callbacks_;
mmentovai@google.comaa13be62008-09-03 03:20:34 +090067 AtExitManager* next_manager_; // Stack of managers to allow shadowing.
68
69 DISALLOW_COPY_AND_ASSIGN(AtExitManager);
70};
71
phajdan.jr@chromium.orge7f133a2009-11-19 18:11:39 +090072#if defined(UNIT_TEST)
73class ShadowingAtExitManager : public AtExitManager {
74 public:
75 ShadowingAtExitManager() : AtExitManager(true) {}
76};
77#endif // defined(UNIT_TEST)
78
mmentovai@google.comaa13be62008-09-03 03:20:34 +090079} // namespace base
80
81#endif // BASE_AT_EXIT_H_