Skip to content

Commit

Permalink
Import Chromium sources r15462
Browse files Browse the repository at this point in the history
  • Loading branch information
bsmedberg committed Jun 29, 2009
1 parent c977ba7 commit d4f21f8
Show file tree
Hide file tree
Showing 784 changed files with 211,093 additions and 0 deletions.
6 changes: 6 additions & 0 deletions ipc/chromium/src/base/DEPS
@@ -0,0 +1,6 @@
include_rules = [
"+third_party/zlib",
"+third_party/libevent",
"+third_party/libjpeg",
"+third_party/dmg_fp",
]
67 changes: 67 additions & 0 deletions ipc/chromium/src/base/at_exit.cc
@@ -0,0 +1,67 @@
// Copyright (c) 2006-2008 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/logging.h"

namespace base {

// 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 AtExitManager* g_top_manager = NULL;

AtExitManager::AtExitManager() : next_manager_(NULL) {
DCHECK(!g_top_manager);
g_top_manager = this;
}

AtExitManager::AtExitManager(bool shadow) : next_manager_(g_top_manager) {
DCHECK(shadow || !g_top_manager);
g_top_manager = this;
}

AtExitManager::~AtExitManager() {
if (!g_top_manager) {
NOTREACHED() << "Tried to ~AtExitManager without an AtExitManager";
return;
}
DCHECK(g_top_manager == this);

ProcessCallbacksNow();
g_top_manager = next_manager_;
}

// static
void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) {
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));
}

// static
void AtExitManager::ProcessCallbacksNow() {
if (!g_top_manager) {
NOTREACHED() << "Tried to ProcessCallbacksNow without an AtExitManager";
return;
}

AutoLock lock(g_top_manager->lock_);

while (!g_top_manager->stack_.empty()) {
CallbackAndParam callback_and_param = g_top_manager->stack_.top();
g_top_manager->stack_.pop();

callback_and_param.func_(callback_and_param.param_);
}
}

} // namespace base
71 changes: 71 additions & 0 deletions ipc/chromium/src/base/at_exit.h
@@ -0,0 +1,71 @@
// Copyright (c) 2006-2008 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.

#ifndef BASE_AT_EXIT_H_
#define BASE_AT_EXIT_H_

#include <stack>

#include "base/basictypes.h"
#include "base/lock.h"

namespace base {

// This class provides a facility similar to the CRT atexit(), except that
// we control when the callbacks are executed. Under Windows for a DLL they
// happen at a really bad time and under the loader lock. This facility is
// mostly used by base::Singleton.
//
// The usage is simple. Early in the main() or WinMain() scope create an
// AtExitManager object on the stack:
// int main(...) {
// base::AtExitManager exit_manager;
//
// }
// When the exit_manager object goes out of scope, all the registered
// callbacks and singleton destructors will be called.

class AtExitManager {
protected:
// This constructor will allow this instance of AtExitManager to be created
// even if one 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:
typedef void (*AtExitCallbackType)(void*);

AtExitManager();

// The dtor calls all the registered callbacks. Do not try to register more
// callbacks after this point.
~AtExitManager();

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

// Calls the functions registered with RegisterCallback in LIFO order. It
// is possible to register new callbacks after calling this function.
static void ProcessCallbacksNow();

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

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

DISALLOW_COPY_AND_ASSIGN(AtExitManager);
};

} // namespace base

#endif // BASE_AT_EXIT_H_
85 changes: 85 additions & 0 deletions ipc/chromium/src/base/at_exit_unittest.cc
@@ -0,0 +1,85 @@
// Copyright (c) 2006-2008 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 "testing/gtest/include/gtest/gtest.h"

namespace {

// Don't test the global AtExitManager, because asking it to process its
// AtExit callbacks can ruin the global state that other tests may depend on.
class ShadowingAtExitManager : public base::AtExitManager {
public:
ShadowingAtExitManager() : AtExitManager(true) {}
};

int g_test_counter_1 = 0;
int g_test_counter_2 = 0;

void IncrementTestCounter1(void* unused) {
++g_test_counter_1;
}

void IncrementTestCounter2(void* unused) {
++g_test_counter_2;
}

void ZeroTestCounters() {
g_test_counter_1 = 0;
g_test_counter_2 = 0;
}

void ExpectCounter1IsZero(void* unused) {
EXPECT_EQ(0, g_test_counter_1);
}

void ExpectParamIsNull(void* param) {
EXPECT_EQ(static_cast<void*>(NULL), param);
}

void ExpectParamIsCounter(void* param) {
EXPECT_EQ(&g_test_counter_1, param);
}

} // namespace

TEST(AtExitTest, Basic) {
ShadowingAtExitManager shadowing_at_exit_manager;

ZeroTestCounters();
base::AtExitManager::RegisterCallback(&IncrementTestCounter1, NULL);
base::AtExitManager::RegisterCallback(&IncrementTestCounter2, NULL);
base::AtExitManager::RegisterCallback(&IncrementTestCounter1, NULL);

EXPECT_EQ(0, g_test_counter_1);
EXPECT_EQ(0, g_test_counter_2);
base::AtExitManager::ProcessCallbacksNow();
EXPECT_EQ(2, g_test_counter_1);
EXPECT_EQ(1, g_test_counter_2);
}

TEST(AtExitTest, LIFOOrder) {
ShadowingAtExitManager shadowing_at_exit_manager;

ZeroTestCounters();
base::AtExitManager::RegisterCallback(&IncrementTestCounter1, NULL);
base::AtExitManager::RegisterCallback(&ExpectCounter1IsZero, NULL);
base::AtExitManager::RegisterCallback(&IncrementTestCounter2, NULL);

EXPECT_EQ(0, g_test_counter_1);
EXPECT_EQ(0, g_test_counter_2);
base::AtExitManager::ProcessCallbacksNow();
EXPECT_EQ(1, g_test_counter_1);
EXPECT_EQ(1, g_test_counter_2);
}

TEST(AtExitTest, Param) {
ShadowingAtExitManager shadowing_at_exit_manager;

base::AtExitManager::RegisterCallback(&ExpectParamIsNull, NULL);
base::AtExitManager::RegisterCallback(&ExpectParamIsCounter,
&g_test_counter_1);
base::AtExitManager::ProcessCallbacksNow();
}
63 changes: 63 additions & 0 deletions ipc/chromium/src/base/atomic_ref_count.h
@@ -0,0 +1,63 @@
// Copyright (c) 2006-2008 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.

// This is a low level implementation of atomic semantics for reference
// counting. Please use base/ref_counted.h directly instead.

#ifndef BASE_ATOMIC_REF_COUNT_H_
#define BASE_ATOMIC_REF_COUNT_H_

#include "base/atomicops.h"

namespace base {

typedef subtle::Atomic32 AtomicRefCount;

// Increment a reference count by "increment", which must exceed 0.
inline void AtomicRefCountIncN(volatile AtomicRefCount *ptr,
AtomicRefCount increment) {
subtle::NoBarrier_AtomicIncrement(ptr, increment);
}

// Decrement a reference count by "decrement", which must exceed 0,
// and return whether the result is non-zero.
// Insert barriers to ensure that state written before the reference count
// became zero will be visible to a thread that has just made the count zero.
inline bool AtomicRefCountDecN(volatile AtomicRefCount *ptr,
AtomicRefCount decrement) {
return subtle::Barrier_AtomicIncrement(ptr, -decrement) != 0;
}

// Increment a reference count by 1.
inline void AtomicRefCountInc(volatile AtomicRefCount *ptr) {
base::AtomicRefCountIncN(ptr, 1);
}

// Decrement a reference count by 1 and return whether the result is non-zero.
// Insert barriers to ensure that state written before the reference count
// became zero will be visible to a thread that has just made the count zero.
inline bool AtomicRefCountDec(volatile AtomicRefCount *ptr) {
return base::AtomicRefCountDecN(ptr, 1);
}

// Return whether the reference count is one. If the reference count is used
// in the conventional way, a refrerence count of 1 implies that the current
// thread owns the reference and no other thread shares it. This call performs
// the test for a reference count of one, and performs the memory barrier
// needed for the owning thread to act on the object, knowing that it has
// exclusive access to the object.
inline bool AtomicRefCountIsOne(volatile AtomicRefCount *ptr) {
return subtle::Acquire_Load(ptr) == 1;
}

// Return whether the reference count is zero. With conventional object
// referencing counting, the object will be destroyed, so the reference count
// should never be zero. Hence this is generally used for a debug check.
inline bool AtomicRefCountIsZero(volatile AtomicRefCount *ptr) {
return subtle::Acquire_Load(ptr) == 0;
}

} // namespace base

#endif // BASE_ATOMIC_REF_COUNT_H_
30 changes: 30 additions & 0 deletions ipc/chromium/src/base/atomic_sequence_num.h
@@ -0,0 +1,30 @@
// Copyright (c) 2006-2008 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.

#ifndef BASE_ATOMIC_SEQUENCE_NUM_H_
#define BASE_ATOMIC_SEQUENCE_NUM_H_

#include "base/atomicops.h"
#include "base/basictypes.h"

namespace base {

class AtomicSequenceNumber {
public:
AtomicSequenceNumber() : seq_(0) { }
explicit AtomicSequenceNumber(base::LinkerInitialized x) { /* seq_ is 0 */ }

int GetNext() {
return static_cast<int>(
base::subtle::NoBarrier_AtomicIncrement(&seq_, 1) - 1);
}

private:
base::subtle::Atomic32 seq_;
DISALLOW_COPY_AND_ASSIGN(AtomicSequenceNumber);
};

} // namespace base

#endif // BASE_ATOMIC_SEQUENCE_NUM_H_

0 comments on commit d4f21f8

Please sign in to comment.