tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

at_exit.cc (2119B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 
      7 #include "base/at_exit.h"
      8 #include "base/logging.h"
      9 
     10 namespace base {
     11 
     12 // Keep a stack of registered AtExitManagers.  We always operate on the most
     13 // recent, and we should never have more than one outside of testing, when we
     14 // use the shadow version of the constructor.  We don't protect this for
     15 // thread-safe access, since it will only be modified in testing.
     16 static AtExitManager* g_top_manager = NULL;
     17 
     18 AtExitManager::AtExitManager() : lock_("AtExitManager"), next_manager_(NULL) {
     19  DCHECK(!g_top_manager);
     20  g_top_manager = this;
     21 }
     22 
     23 AtExitManager::AtExitManager(bool shadow)
     24    : lock_("AtExitManager"), next_manager_(g_top_manager) {
     25  DCHECK(shadow || !g_top_manager);
     26  g_top_manager = this;
     27 }
     28 
     29 AtExitManager::~AtExitManager() {
     30  if (!g_top_manager) {
     31    NOTREACHED() << "Tried to ~AtExitManager without an AtExitManager";
     32    return;
     33  }
     34  DCHECK(g_top_manager == this);
     35 
     36  ProcessCallbacksNow();
     37  g_top_manager = next_manager_;
     38 }
     39 
     40 // static
     41 void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) {
     42  if (!g_top_manager) {
     43    NOTREACHED() << "Tried to RegisterCallback without an AtExitManager";
     44    return;
     45  }
     46 
     47  DCHECK(func);
     48 
     49  mozilla::MutexAutoLock lock(g_top_manager->lock_);
     50  g_top_manager->stack_.push(CallbackAndParam(func, param));
     51 }
     52 
     53 // static
     54 void AtExitManager::ProcessCallbacksNow() {
     55  if (!g_top_manager) {
     56    NOTREACHED() << "Tried to ProcessCallbacksNow without an AtExitManager";
     57    return;
     58  }
     59 
     60  mozilla::MutexAutoLock lock(g_top_manager->lock_);
     61 
     62  while (!g_top_manager->stack_.empty()) {
     63    CallbackAndParam callback_and_param = g_top_manager->stack_.top();
     64    g_top_manager->stack_.pop();
     65 
     66    callback_and_param.func_(callback_and_param.param_);
     67  }
     68 }
     69 
     70 // static
     71 bool AtExitManager::AlreadyRegistered() { return !!g_top_manager; }
     72 
     73 }  // namespace base