blob: 9e75a3fafdd7031b0711df3d0b54660d29ef24c1 [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"
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
42 // the callback function is void func().
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
45 // Calls the functions registered with RegisterCallback in LIFO order. It
46 // is possible to register new callbacks after calling this function.
47 static void ProcessCallbacksNow();
48
erg@google.comd5fffd42011-01-08 03:06:45 +090049 protected:
50 // This constructor will allow this instance of AtExitManager to be created
51 // even if one already exists. This should only be used for testing!
52 // AtExitManagers are kept on a global stack, and it will be removed during
53 // destruction. This allows you to shadow another AtExitManager.
54 explicit AtExitManager(bool shadow);
55
mmentovai@google.comaa13be62008-09-03 03:20:34 +090056 private:
deanm@google.comf6299e72008-09-08 18:06:51 +090057 struct CallbackAndParam {
58 CallbackAndParam(AtExitCallbackType func, void* param)
59 : func_(func), param_(param) { }
60 AtExitCallbackType func_;
61 void* param_;
62 };
63
brettw@chromium.orgabe477a2011-01-21 13:55:52 +090064 base::Lock lock_;
deanm@google.comf6299e72008-09-08 18:06:51 +090065 std::stack<CallbackAndParam> stack_;
mmentovai@google.comaa13be62008-09-03 03:20:34 +090066 AtExitManager* next_manager_; // Stack of managers to allow shadowing.
67
68 DISALLOW_COPY_AND_ASSIGN(AtExitManager);
69};
70
phajdan.jr@chromium.orge7f133a2009-11-19 18:11:39 +090071#if defined(UNIT_TEST)
72class ShadowingAtExitManager : public AtExitManager {
73 public:
74 ShadowingAtExitManager() : AtExitManager(true) {}
75};
76#endif // defined(UNIT_TEST)
77
mmentovai@google.comaa13be62008-09-03 03:20:34 +090078} // namespace base
79
80#endif // BASE_AT_EXIT_H_