blob: 613c9fe7d1729f8a9590e50abc3f8547c0676bb8 [file] [log] [blame]
erg@google.comd5fffd42011-01-08 03:06:45 +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_
thakis@chromium.org01d14522010-07-27 08:08:24 +09007#pragma once
mmentovai@google.comaa13be62008-09-03 03:20:34 +09008
9#include <stack>
10
darin@chromium.orge585bed2011-08-06 00:34:00 +090011#include "base/base_export.h"
mmentovai@google.comaa13be62008-09-03 03:20:34 +090012#include "base/basictypes.h"
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090013#include "base/callback.h"
brettw@chromium.orgabe477a2011-01-21 13:55:52 +090014#include "base/synchronization/lock.h"
mmentovai@google.comaa13be62008-09-03 03:20:34 +090015
16namespace 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;
maruel@chromium.org8fe7adc2009-03-04 00:01:12 +090027//
mmentovai@google.comaa13be62008-09-03 03:20:34 +090028// }
29// When the exit_manager object goes out of scope, all the registered
30// callbacks and singleton destructors will be called.
31
darin@chromium.orge585bed2011-08-06 00:34:00 +090032class BASE_EXPORT AtExitManager {
mmentovai@google.comaa13be62008-09-03 03:20:34 +090033 public:
deanm@google.comf6299e72008-09-08 18:06:51 +090034 typedef void (*AtExitCallbackType)(void*);
mmentovai@google.comaa13be62008-09-03 03:20:34 +090035
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
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090043 // the callback function is void func(void*).
deanm@google.comf6299e72008-09-08 18:06:51 +090044 static void RegisterCallback(AtExitCallbackType func, void* param);
mmentovai@google.comaa13be62008-09-03 03:20:34 +090045
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090046 // Registers the specified task to be called at exit.
47 static void RegisterTask(base::Closure task);
48
mmentovai@google.comaa13be62008-09-03 03:20:34 +090049 // 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
erg@google.comd5fffd42011-01-08 03:06:45 +090053 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
mmentovai@google.comaa13be62008-09-03 03:20:34 +090060 private:
brettw@chromium.orgabe477a2011-01-21 13:55:52 +090061 base::Lock lock_;
apatrick@chromium.org035f4af2011-09-07 08:14:47 +090062 std::stack<base::Closure> stack_;
mmentovai@google.comaa13be62008-09-03 03:20:34 +090063 AtExitManager* next_manager_; // Stack of managers to allow shadowing.
64
65 DISALLOW_COPY_AND_ASSIGN(AtExitManager);
66};
67
phajdan.jr@chromium.orge7f133a2009-11-19 18:11:39 +090068#if defined(UNIT_TEST)
69class ShadowingAtExitManager : public AtExitManager {
70 public:
71 ShadowingAtExitManager() : AtExitManager(true) {}
72};
73#endif // defined(UNIT_TEST)
74
mmentovai@google.comaa13be62008-09-03 03:20:34 +090075} // namespace base
76
77#endif // BASE_AT_EXIT_H_