Skip to content

Commit

Permalink
Support for registering arbitrary Tasks with AtExitManager.
Browse files Browse the repository at this point in the history
Previously it was limitted to functions taling a single void* argument.

Review URL: http://codereview.chromium.org/7831021

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99856 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
apatrick@chromium.org committed Sep 6, 2011
1 parent d3a250f commit 762de91
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 16 deletions.
17 changes: 11 additions & 6 deletions base/at_exit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
#include <stddef.h>
#include <ostream>

#include "base/bind.h"
#include "base/logging.h"
#include "base/task.h"

namespace base {

Expand Down Expand Up @@ -41,15 +43,19 @@ AtExitManager::~AtExitManager() {

// static
void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) {
DCHECK(func);
RegisterTask(base::Bind(func, param));
}

// static
void AtExitManager::RegisterTask(base::Closure task) {
if (!g_top_manager) {
NOTREACHED() << "Tried to RegisterCallback without an AtExitManager";
return;
}

DCHECK(func);

AutoLock lock(g_top_manager->lock_);
g_top_manager->stack_.push(CallbackAndParam(func, param));
g_top_manager->stack_.push(task);
}

// static
Expand All @@ -62,10 +68,9 @@ void AtExitManager::ProcessCallbacksNow() {
AutoLock lock(g_top_manager->lock_);

while (!g_top_manager->stack_.empty()) {
CallbackAndParam callback_and_param = g_top_manager->stack_.top();
base::Closure task = g_top_manager->stack_.top();
task.Run();
g_top_manager->stack_.pop();

callback_and_param.func_(callback_and_param.param_);
}
}

Expand Down
15 changes: 6 additions & 9 deletions base/at_exit.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/synchronization/lock.h"

namespace base {
Expand Down Expand Up @@ -39,9 +40,12 @@ class BASE_EXPORT AtExitManager {
~AtExitManager();

// Registers the specified function to be called at exit. The prototype of
// the callback function is void func().
// the callback function is void func(void*).
static void RegisterCallback(AtExitCallbackType func, void* param);

// Registers the specified task to be called at exit.
static void RegisterTask(base::Closure task);

// Calls the functions registered with RegisterCallback in LIFO order. It
// is possible to register new callbacks after calling this function.
static void ProcessCallbacksNow();
Expand All @@ -54,15 +58,8 @@ class BASE_EXPORT AtExitManager {
explicit AtExitManager(bool shadow);

private:
struct CallbackAndParam {
CallbackAndParam(AtExitCallbackType func, void* param)
: func_(func), param_(param) { }
AtExitCallbackType func_;
void* param_;
};

base::Lock lock_;
std::stack<CallbackAndParam> stack_;
std::stack<base::Closure> stack_;
AtExitManager* next_manager_; // Stack of managers to allow shadowing.

DISALLOW_COPY_AND_ASSIGN(AtExitManager);
Expand Down
10 changes: 9 additions & 1 deletion base/at_exit_unittest.cc
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/at_exit.h"
#include "base/bind.h"

#include "testing/gtest/include/gtest/gtest.h"

Expand Down Expand Up @@ -77,3 +78,10 @@ TEST_F(AtExitTest, Param) {
&g_test_counter_1);
base::AtExitManager::ProcessCallbacksNow();
}

TEST_F(AtExitTest, Task) {
ZeroTestCounters();
base::AtExitManager::RegisterTask(base::Bind(ExpectParamIsCounter,
&g_test_counter_1));
base::AtExitManager::ProcessCallbacksNow();
}

0 comments on commit 762de91

Please sign in to comment.