Home | History | Annotate | Download | only in base
      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 
     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_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)
     72 class 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