1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/at_exit.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,72 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "base/at_exit.h" 1.9 +#include "base/logging.h" 1.10 + 1.11 +namespace base { 1.12 + 1.13 +// Keep a stack of registered AtExitManagers. We always operate on the most 1.14 +// recent, and we should never have more than one outside of testing, when we 1.15 +// use the shadow version of the constructor. We don't protect this for 1.16 +// thread-safe access, since it will only be modified in testing. 1.17 +static AtExitManager* g_top_manager = NULL; 1.18 + 1.19 +AtExitManager::AtExitManager() : next_manager_(NULL) { 1.20 + DCHECK(!g_top_manager); 1.21 + g_top_manager = this; 1.22 +} 1.23 + 1.24 +AtExitManager::AtExitManager(bool shadow) : next_manager_(g_top_manager) { 1.25 + DCHECK(shadow || !g_top_manager); 1.26 + g_top_manager = this; 1.27 +} 1.28 + 1.29 +AtExitManager::~AtExitManager() { 1.30 + if (!g_top_manager) { 1.31 + NOTREACHED() << "Tried to ~AtExitManager without an AtExitManager"; 1.32 + return; 1.33 + } 1.34 + DCHECK(g_top_manager == this); 1.35 + 1.36 + ProcessCallbacksNow(); 1.37 + g_top_manager = next_manager_; 1.38 +} 1.39 + 1.40 +// static 1.41 +void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) { 1.42 + if (!g_top_manager) { 1.43 + NOTREACHED() << "Tried to RegisterCallback without an AtExitManager"; 1.44 + return; 1.45 + } 1.46 + 1.47 + DCHECK(func); 1.48 + 1.49 + AutoLock lock(g_top_manager->lock_); 1.50 + g_top_manager->stack_.push(CallbackAndParam(func, param)); 1.51 +} 1.52 + 1.53 +// static 1.54 +void AtExitManager::ProcessCallbacksNow() { 1.55 + if (!g_top_manager) { 1.56 + NOTREACHED() << "Tried to ProcessCallbacksNow without an AtExitManager"; 1.57 + return; 1.58 + } 1.59 + 1.60 + AutoLock lock(g_top_manager->lock_); 1.61 + 1.62 + while (!g_top_manager->stack_.empty()) { 1.63 + CallbackAndParam callback_and_param = g_top_manager->stack_.top(); 1.64 + g_top_manager->stack_.pop(); 1.65 + 1.66 + callback_and_param.func_(callback_and_param.param_); 1.67 + } 1.68 +} 1.69 + 1.70 +// static 1.71 +bool AtExitManager::AlreadyRegistered() { 1.72 + return !!g_top_manager; 1.73 +} 1.74 + 1.75 +} // namespace base