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#pragma once
8
9#include <stack>
10
11#include "base/base_api.h"
12#include "base/basictypes.h"
13#include "base/synchronization/lock.h"
14
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;
26//
27// }
28// When the exit_manager object goes out of scope, all the registered
29// callbacks and singleton destructors will be called.
30
31class BASE_API 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().
43  static void RegisterCallback(AtExitCallbackType func, void* param);
44
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
49 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
56 private:
57  struct CallbackAndParam {
58    CallbackAndParam(AtExitCallbackType func, void* param)
59        : func_(func), param_(param) { }
60    AtExitCallbackType func_;
61    void* param_;
62  };
63
64  base::Lock lock_;
65  std::stack<CallbackAndParam> stack_;
66  AtExitManager* next_manager_;  // Stack of managers to allow shadowing.
67
68  DISALLOW_COPY_AND_ASSIGN(AtExitManager);
69};
70
71#if defined(UNIT_TEST)
72class ShadowingAtExitManager : public AtExitManager {
73 public:
74  ShadowingAtExitManager() : AtExitManager(true) {}
75};
76#endif  // defined(UNIT_TEST)
77
78}  // namespace base
79
80#endif  // BASE_AT_EXIT_H_
81