Skip to content

Commit

Permalink
Allow multiple AtExitManagers to be chained in a stack, this allows m…
Browse files Browse the repository at this point in the history
…uch easier testing for code that is expecting to be run via an AtExitManager. This actually cleaned up a lot of the at exit code.

Clean up singleton_dll_unittest.  It is no longer windows specific DLL, and now is much simpler, and builds and runs cross platform.

BUG=1314043

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@646 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
deanm@google.com committed Aug 11, 2008
1 parent 663fe3c commit 4ac8f67
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 535 deletions.
19 changes: 0 additions & 19 deletions base/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -200,23 +200,6 @@ if env['PLATFORM'] == 'win32':
],
)


env_tests_dll = env_tests.Clone()
env_tests_dll.Append(
CPPDEFINES = [
'_WINDLL',
'SINGLETON_UNITTEST_EXPORTS',
],
)
dll = env_tests_dll.ChromeSharedLibrary(['singleton_dll_unittest.dll',
'singleton_dll_unittest.lib',
'singleton_dll_unittest.ilk',
'singleton_dll_unittest.pdb'],
['singleton_dll_unittest.cc',
'build/singleton_dll_unittest.def'])
i = env.Install('$TARGET_ROOT', dll[0])
env.Alias('base', i)

env_tests.ChromeTestProgram(['debug_message.exe',
'debug_message.ilk',
'debug_message.pdb'],
Expand Down Expand Up @@ -269,8 +252,6 @@ test_files = [
'win_util_unittest.cc',
'word_iterator_unittest.cc',
'wmi_util_unittest.cc',

dll[1],
]

if env['PLATFORM'] == 'win32':
Expand Down
79 changes: 42 additions & 37 deletions base/at_exit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,58 +30,63 @@
#include "base/at_exit.h"
#include "base/logging.h"

namespace {

std::stack<base::AtExitCallbackType>* g_atexit_queue = NULL;
Lock* g_atexit_lock = NULL;

void ProcessCallbacks() {
if (!g_atexit_queue)
return;
base::AtExitCallbackType func = NULL;
while(!g_atexit_queue->empty()) {
func = g_atexit_queue->top();
g_atexit_queue->pop();
if (func)
func();
}
}

} // namespace
// Keep a stack of registered AtExitManagers. We always operate on the most
// recent, and we should never have more than one outside of testing, when we
// use the shadow version of the constructor. We don't protect this for
// thread-safe access, since it will only be modified in testing.
static std::stack<base::AtExitManager*> g_managers;

namespace base {

AtExitManager::AtExitManager() {
DCHECK(NULL == g_atexit_queue);
DCHECK(NULL == g_atexit_lock);
g_atexit_lock = &lock_;
g_atexit_queue = &atexit_queue_;
DCHECK(g_managers.empty());
g_managers.push(this);
}

AtExitManager::AtExitManager(bool shadow) {
DCHECK(shadow || g_managers.empty());
g_managers.push(this);
}

AtExitManager::~AtExitManager() {
AutoLock lock(lock_);
ProcessCallbacks();
g_atexit_queue = NULL;
g_atexit_lock = NULL;
if (g_managers.empty()) {
NOTREACHED() << "Tried to ~AtExitManager without a AtExitManager";
return;
}
DCHECK(g_managers.top() == this);

ProcessCallbacksNow();
g_managers.pop();
}

// static
void AtExitManager::RegisterCallback(AtExitCallbackType func) {
DCHECK(NULL != g_atexit_queue);
DCHECK(NULL != g_atexit_lock);
if (!g_atexit_lock)
if (g_managers.empty()) {
NOTREACHED() << "Tried to RegisterCallback without a AtExitManager";
return;
AutoLock lock(*g_atexit_lock);
if (g_atexit_queue)
g_atexit_queue->push(func);
}

AtExitManager* manager = g_managers.top();
AutoLock lock(manager->lock_);
manager->stack_.push(func);
}

// static
void AtExitManager::ProcessCallbacksNow() {
DCHECK(NULL != g_atexit_lock);
if (!g_atexit_lock)
if (g_managers.empty()) {
NOTREACHED() << "Tried to RegisterCallback without a AtExitManager";
return;
AutoLock lock(*g_atexit_lock);
DCHECK(NULL != g_atexit_queue);
ProcessCallbacks();
}

AtExitManager* manager = g_managers.top();
AutoLock lock(manager->lock_);

while (!manager->stack_.empty()) {
base::AtExitCallbackType func = manager->stack_.top();
manager->stack_.pop();
if (func)
func();
}
}

} // namespace base
8 changes: 7 additions & 1 deletion base/at_exit.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ typedef void (*AtExitCallbackType)();
// callbacks and singleton destructors will be called.

class AtExitManager {
protected:
// This constructor will allow this instance of AtExitManager to be created
// even if on already exists. This should only be used for testing!
// AtExitManagers are kept on a global stack, and it will be removed during
// destruction. This allows you to shadow another AtExitManager.
AtExitManager(bool shadow);
public:
AtExitManager();

Expand All @@ -71,7 +77,7 @@ class AtExitManager {

private:
Lock lock_;
std::stack<base::AtExitCallbackType> atexit_queue_;
std::stack<base::AtExitCallbackType> stack_;
DISALLOW_EVIL_CONSTRUCTORS(AtExitManager);
};

Expand Down
6 changes: 0 additions & 6 deletions base/base.sln
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\third_party\li
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\third_party\zlib\zlib.vcproj", "{8423AF0D-4B88-4EBF-94E1-E4D00D00E21C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "singleton_dll_unittest", "build\singleton_unittest.vcproj", "{E457F2FB-4708-4001-9B1C-275D7BD7F2A8}"
ProjectSection(ProjectDependencies) = postProject
{1832A374-8A74-4F9E-B536-69A699B3E165} = {1832A374-8A74-4F9E-B536-69A699B3E165}
{8C27D792-2648-4F5E-9ED0-374276327308} = {8C27D792-2648-4F5E-9ED0-374276327308}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "..\testing\gtest.vcproj", "{BFE8E2A7-3B3B-43B0-A994-3058B852DB8B}"
EndProject
Global
Expand Down
9 changes: 0 additions & 9 deletions base/build/singleton_dll_unittest.def

This file was deleted.

15 changes: 0 additions & 15 deletions base/build/singleton_dll_unittest.vsprops

This file was deleted.

157 changes: 0 additions & 157 deletions base/build/singleton_unittest.vcproj

This file was deleted.

Loading

0 comments on commit 4ac8f67

Please sign in to comment.