summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-20 22:11:47 +0000
committerevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-20 22:11:47 +0000
commitfa87a2527ca8c0bcef92d8e44791332782936911 (patch)
tree04dc5d1e6881f8356f91203a386648057b20d924 /base
parent4f64d0af5908e36d356c834005d08cca98d579fe (diff)
downloadchromium_src-fa87a2527ca8c0bcef92d8e44791332782936911.zip
chromium_src-fa87a2527ca8c0bcef92d8e44791332782936911.tar.gz
chromium_src-fa87a2527ca8c0bcef92d8e44791332782936911.tar.bz2
Revert. Failing unit tests.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1118 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/message_loop.cc8
-rw-r--r--base/message_loop.h2
-rw-r--r--base/stats_table.cc10
-rw-r--r--base/thread.cc8
-rw-r--r--base/thread_local_storage.h81
-rw-r--r--base/thread_local_storage_posix.cc38
-rw-r--r--base/thread_local_storage_win.cc53
-rw-r--r--base/tracked_objects.cc25
8 files changed, 90 insertions, 135 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc
index bdf99f0..caec847 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -39,9 +39,7 @@
// a TLS index to the message loop for the current thread
// Note that if we start doing complex stuff in other static initializers
// this could cause problems.
-// TODO(evanm): this shouldn't rely on static initialization.
-// static
-TLSSlot MessageLoop::tls_index_;
+/*static*/ TLSSlot MessageLoop::tls_index_ = ThreadLocalStorage::Alloc();
//------------------------------------------------------------------------------
@@ -85,7 +83,7 @@ MessageLoop::MessageLoop()
exception_restoration_(false),
state_(NULL) {
DCHECK(!current()) << "should only have one message loop per thread";
- tls_index_.Set(this);
+ ThreadLocalStorage::Set(tls_index_, this);
// TODO(darin): Generalize this to support instantiating different pumps.
#if defined(OS_WIN)
pump_ = new base::MessagePumpWin();
@@ -102,7 +100,7 @@ MessageLoop::~MessageLoop() {
WillDestroyCurrentMessageLoop());
// OK, now make it so that no one can find us.
- tls_index_.Set(NULL);
+ ThreadLocalStorage::Set(tls_index_, NULL);
DCHECK(!state_);
diff --git a/base/message_loop.h b/base/message_loop.h
index e11b73f..3821519 100644
--- a/base/message_loop.h
+++ b/base/message_loop.h
@@ -194,7 +194,7 @@ class MessageLoop : public base::MessagePump::Delegate {
// Returns the MessageLoop object for the current thread, or null if none.
static MessageLoop* current() {
- return static_cast<MessageLoop*>(tls_index_.Get());
+ return static_cast<MessageLoop*>(ThreadLocalStorage::Get(tls_index_));
}
// Returns the TimerManager object for the current thread.
diff --git a/base/stats_table.cc b/base/stats_table.cc
index 8b10662..23c736a 100644
--- a/base/stats_table.cc
+++ b/base/stats_table.cc
@@ -254,7 +254,7 @@ StatsTable* StatsTable::global_table_ = NULL;
StatsTable::StatsTable(const std::wstring& name, int max_threads,
int max_counters)
- : tls_index_(SlotReturnFunction) {
+ : tls_index_(ThreadLocalStorage::Alloc(SlotReturnFunction)) {
int table_size =
AlignedSize(sizeof(TableHeader)) +
AlignedSize((max_counters * sizeof(wchar_t) * kMaxCounterNameLength)) +
@@ -285,7 +285,7 @@ StatsTable::~StatsTable() {
// Return ThreadLocalStorage. At this point, if any registered threads
// still exist, they cannot Unregister.
- tls_index_.Free();
+ ThreadLocalStorage::Free(tls_index_);
// Cleanup our shared memory.
delete impl_;
@@ -329,13 +329,13 @@ int StatsTable::RegisterThread(const std::wstring& name) {
StatsTableTLSData* data = new StatsTableTLSData;
data->table = this;
data->slot = slot;
- tls_index_.Set(data);
+ ThreadLocalStorage::Set(tls_index_, data);
return slot;
}
StatsTableTLSData* StatsTable::GetTLSData() const {
StatsTableTLSData* data =
- static_cast<StatsTableTLSData*>(tls_index_.Get());
+ static_cast<StatsTableTLSData*>(ThreadLocalStorage::Get(tls_index_));
if (!data)
return NULL;
@@ -355,7 +355,7 @@ void StatsTable::UnregisterThread() {
*name = L'\0';
// Remove the calling thread's TLS so that it cannot use the slot.
- tls_index_.Set(NULL);
+ ThreadLocalStorage::Set(tls_index_, NULL);
delete data;
}
diff --git a/base/thread.cc b/base/thread.cc
index 6998deb..629c7e0 100644
--- a/base/thread.cc
+++ b/base/thread.cc
@@ -69,6 +69,7 @@ Thread::Thread(const char *name)
thread_id_(0),
message_loop_(NULL),
name_(name) {
+ DCHECK(tls_index_) << "static initializer failed";
}
Thread::~Thread() {
@@ -81,19 +82,18 @@ Thread::~Thread() {
// Thread to setup and run a MessageLoop.
// Note that if we start doing complex stuff in other static initializers
// this could cause problems.
-// TODO(evanm): this shouldn't rely on static initialization.
-TLSSlot Thread::tls_index_;
+TLSSlot Thread::tls_index_ = ThreadLocalStorage::Alloc();
void Thread::SetThreadWasQuitProperly(bool flag) {
#ifndef NDEBUG
- tls_index_.Set(reinterpret_cast<void*>(flag));
+ ThreadLocalStorage::Set(tls_index_, reinterpret_cast<void*>(flag));
#endif
}
bool Thread::GetThreadWasQuitProperly() {
bool quit_properly = true;
#ifndef NDEBUG
- quit_properly = (tls_index_.Get() != 0);
+ quit_properly = (ThreadLocalStorage::Get(tls_index_) != 0);
#endif
return quit_properly;
}
diff --git a/base/thread_local_storage.h b/base/thread_local_storage.h
index fba90ae..245a73f 100644
--- a/base/thread_local_storage.h
+++ b/base/thread_local_storage.h
@@ -32,62 +32,43 @@
#include "base/basictypes.h"
-#if defined(OS_POSIX)
+#if defined(OS_WIN)
+typedef int TLSSlot;
+#elif defined(OS_POSIX)
#include <pthread.h>
-#endif
+typedef pthread_key_t TLSSlot;
+#endif // OS_*
-// Wrapper for thread local storage. This class doesn't do much except provide
-// an API for portability.
+// Wrapper for thread local storage. This class doesn't
+// do much except provide an API for portability later.
class ThreadLocalStorage {
public:
-
- // Prototype for the TLS destructor function, which can be optionally used to
- // cleanup thread local storage on thread exit. 'value' is the data that is
- // stored in thread local storage.
+ // Prototype for the TLS destructor function, which can be
+ // optionally used to cleanup thread local storage on
+ // thread exit. 'value' is the data that is stored
+ // in thread local storage.
typedef void (*TLSDestructorFunc)(void* value);
- // A key representing one value stored in TLS.
- class Slot {
- public:
- Slot(TLSDestructorFunc destructor = NULL);
-
- // This constructor should be used for statics.
- // It returns an uninitialized Slot.
- explicit Slot(base::LinkerInitialized x) {}
-
- // Set up the TLS slot. Called by the constructor.
- // 'destructor' is a pointer to a function to perform per-thread cleanup of
- // this object. If set to NULL, no cleanup is done for this TLS slot.
- // Returns false on error.
- bool Initialize(TLSDestructorFunc destructor);
-
- // Free a previously allocated TLS 'slot'.
- // If a destructor was set for this slot, removes
- // the destructor so that remaining threads exiting
- // will not free data.
- void Free();
+ // Allocate a TLS 'slot'.
+ // 'destructor' is a pointer to a function to perform
+ // per-thread cleanup of this object. If set to NULL,
+ // no cleanup is done for this TLS slot.
+ // Returns an index > 0 on success, or -1 on failure.
+ static TLSSlot Alloc(TLSDestructorFunc destructor = NULL);
- // Get the thread-local value stored in slot 'slot'.
- // Values are guaranteed to initially be zero.
- void* Get() const;
+ // Free a previously allocated TLS 'slot'.
+ // If a destructor was set for this slot, removes
+ // the destructor so that remaining threads exiting
+ // will not free data.
+ static void Free(TLSSlot slot);
- // Set the thread-local value stored in slot 'slot' to
- // value 'value'.
- void Set(void* value);
+ // Get the thread-local value stored in slot 'slot'.
+ // Values are guaranteed to initially be zero.
+ static void* Get(TLSSlot slot);
- bool initialized() const { return initialized_; }
-
- private:
- // The internals of this struct should be considered private.
- bool initialized_;
-#if defined(OS_WIN)
- int slot_;
-#elif defined(OS_POSIX)
- pthread_key_t key_;
-#endif
-
- DISALLOW_COPY_AND_ASSIGN(Slot);
- };
+ // Set the thread-local value stored in slot 'slot' to
+ // value 'value'.
+ static void Set(TLSSlot slot, void* value);
#if defined(OS_WIN)
// Function called when on thread exit to call TLS
@@ -109,11 +90,7 @@ class ThreadLocalStorage {
static TLSDestructorFunc tls_destructors_[kThreadLocalStorageSize];
#endif // OS_WIN
- DISALLOW_COPY_AND_ASSIGN(ThreadLocalStorage);
+ DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage);
};
-// Temporary backwards-compatible name.
-// TODO(evanm): replace all usage of TLSSlot.
-typedef ThreadLocalStorage::Slot TLSSlot;
-
#endif // BASE_THREAD_LOCAL_STORAGE_H_
diff --git a/base/thread_local_storage_posix.cc b/base/thread_local_storage_posix.cc
index 7c24e59..bcc982f 100644
--- a/base/thread_local_storage_posix.cc
+++ b/base/thread_local_storage_posix.cc
@@ -31,39 +31,23 @@
#include "base/logging.h"
-ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor)
- : initialized_(false) {
- Initialize(destructor);
-}
-
-bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) {
- DCHECK(!initialized_);
- int error = pthread_key_create(&key_, destructor);
- if (error) {
+TLSSlot ThreadLocalStorage::Alloc(TLSDestructorFunc destructor) {
+ TLSSlot key;
+ int error = pthread_key_create(&key, destructor);
+ if (error)
NOTREACHED();
- return false;
- }
- initialized_ = true;
- return true;
+ return key;
}
-void ThreadLocalStorage::Slot::Free() {
- DCHECK(initialized_);
- int error = pthread_key_delete(key_);
- if (error)
- NOTREACHED();
- initialized_ = false;
+void ThreadLocalStorage::Free(TLSSlot slot) {
+ pthread_key_delete(slot);
}
-void* ThreadLocalStorage::Slot::Get() const {
- DCHECK(initialized_);
- return pthread_getspecific(key_);
+void* ThreadLocalStorage::Get(TLSSlot slot) {
+ return pthread_getspecific(slot);
}
-void ThreadLocalStorage::Slot::Set(void* value) {
- DCHECK(initialized_);
- int error = pthread_setspecific(key_, value);
- if (error)
- NOTREACHED();
+void ThreadLocalStorage::Set(TLSSlot slot, void* value) {
+ pthread_setspecific(slot, value);
}
diff --git a/base/thread_local_storage_win.cc b/base/thread_local_storage_win.cc
index 154935a..8157e88 100644
--- a/base/thread_local_storage_win.cc
+++ b/base/thread_local_storage_win.cc
@@ -55,7 +55,7 @@ long ThreadLocalStorage::tls_max_ = 1;
ThreadLocalStorage::TLSDestructorFunc
ThreadLocalStorage::tls_destructors_[kThreadLocalStorageSize];
-void** ThreadLocalStorage::Initialize() {
+void **ThreadLocalStorage::Initialize() {
if (tls_key_ == TLS_OUT_OF_INDEXES) {
long value = TlsAlloc();
DCHECK(value != TLS_OUT_OF_INDEXES);
@@ -73,59 +73,52 @@ void** ThreadLocalStorage::Initialize() {
DCHECK(TlsGetValue(tls_key_) == NULL);
// Create an array to store our data.
- void** tls_data = new void*[kThreadLocalStorageSize];
+ void **tls_data = new void*[kThreadLocalStorageSize];
memset(tls_data, 0, sizeof(void*[kThreadLocalStorageSize]));
TlsSetValue(tls_key_, tls_data);
return tls_data;
}
-ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor)
- : initialized_(false) {
- Initialize(destructor);
-}
-
-bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) {
+TLSSlot ThreadLocalStorage::Alloc(TLSDestructorFunc destructor) {
if (tls_key_ == TLS_OUT_OF_INDEXES || !TlsGetValue(tls_key_))
- ThreadLocalStorage::Initialize();
+ Initialize();
// Grab a new slot.
- slot_ = InterlockedIncrement(&tls_max_) - 1;
- if (slot_ >= kThreadLocalStorageSize) {
+ int slot = InterlockedIncrement(&tls_max_) - 1;
+ if (slot >= kThreadLocalStorageSize) {
NOTREACHED();
- return false;
+ return -1;
}
// Setup our destructor.
- tls_destructors_[slot_] = destructor;
- initialized_ = true;
- return true;
+ tls_destructors_[slot] = destructor;
+ return slot;
}
-void ThreadLocalStorage::Slot::Free() {
+void ThreadLocalStorage::Free(TLSSlot slot) {
// At this time, we don't reclaim old indices for TLS slots.
// So all we need to do is wipe the destructor.
- tls_destructors_[slot_] = NULL;
- initialized_ = false;
+ tls_destructors_[slot] = NULL;
}
-void* ThreadLocalStorage::Slot::Get() const {
- void** tls_data = static_cast<void**>(TlsGetValue(tls_key_));
+void* ThreadLocalStorage::Get(TLSSlot slot) {
+ void **tls_data = static_cast<void**>(TlsGetValue(tls_key_));
if (!tls_data)
- tls_data = ThreadLocalStorage::Initialize();
- DCHECK(slot_ >= 0 && slot_ < kThreadLocalStorageSize);
- return tls_data[slot_];
+ tls_data = Initialize();
+ DCHECK(slot >= 0 && slot < kThreadLocalStorageSize);
+ return tls_data[slot];
}
-void ThreadLocalStorage::Slot::Set(void* value) {
- void** tls_data = static_cast<void**>(TlsGetValue(tls_key_));
+void ThreadLocalStorage::Set(TLSSlot slot, void* value) {
+ void **tls_data = static_cast<void**>(TlsGetValue(tls_key_));
if (!tls_data)
- tls_data = ThreadLocalStorage::Initialize();
- DCHECK(slot_ >= 0 && slot_ < kThreadLocalStorageSize);
- tls_data[slot_] = value;
+ tls_data = Initialize();
+ DCHECK(slot >= 0 && slot < kThreadLocalStorageSize);
+ tls_data[slot] = value;
}
void ThreadLocalStorage::ThreadExit() {
- void** tls_data = static_cast<void**>(TlsGetValue(tls_key_));
+ void **tls_data = static_cast<void**>(TlsGetValue(tls_key_));
// Maybe we have never initialized TLS for this thread.
if (!tls_data)
@@ -133,7 +126,7 @@ void ThreadLocalStorage::ThreadExit() {
for (int slot = 0; slot < tls_max_; slot++) {
if (tls_destructors_[slot] != NULL) {
- void* value = tls_data[slot];
+ void *value = tls_data[slot];
tls_destructors_[slot](value);
}
}
diff --git a/base/tracked_objects.cc b/base/tracked_objects.cc
index 83a7fbd..b683a87 100644
--- a/base/tracked_objects.cc
+++ b/base/tracked_objects.cc
@@ -35,9 +35,9 @@
namespace tracked_objects {
-// A TLS slot to the TrackRegistry for the current thread.
+// a TLS index to the TrackRegistry for the current thread.
// static
-TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED);
+TLSSlot ThreadData::tls_index_ = -1;
//------------------------------------------------------------------------------
// Death data tallies durations when a death takes place.
@@ -104,14 +104,15 @@ Lock ThreadData::list_lock_;
// static
ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED;
-ThreadData::ThreadData() : message_loop_(MessageLoop::current()) {}
+ThreadData::ThreadData() : message_loop_(MessageLoop::current()) {}
// static
ThreadData* ThreadData::current() {
- if (!tls_index_.initialized())
- return NULL;
+ if (-1 == tls_index_)
+ return NULL; // not yet initialized.
- ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get());
+ ThreadData* registry =
+ static_cast<ThreadData*>(ThreadLocalStorage::Get(tls_index_));
if (!registry) {
// We have to create a new registry for ThreadData.
bool too_late_to_create = false;
@@ -131,7 +132,7 @@ ThreadData* ThreadData::current() {
delete registry;
registry = NULL;
} else {
- tls_index_.Set(registry);
+ ThreadLocalStorage::Set(tls_index_, registry);
}
}
return registry;
@@ -343,9 +344,11 @@ bool ThreadData::StartTracking(bool status) {
status_ = SHUTDOWN;
return true;
}
+ TLSSlot tls_index = ThreadLocalStorage::Alloc();
AutoLock lock(list_lock_);
DCHECK(status_ == UNINITIALIZED);
- CHECK(tls_index_.Initialize(NULL));
+ tls_index_ = tls_index;
+ CHECK(-1 != tls_index_);
status_ = ACTIVE;
return true;
}
@@ -398,9 +401,9 @@ void ThreadData::ShutdownSingleThreadedCleanup() {
delete next_thread_data; // Includes all Death Records.
}
- CHECK(tls_index_.initialized());
- tls_index_.Free();
- DCHECK(!tls_index_.initialized());
+ CHECK(-1 != tls_index_);
+ ThreadLocalStorage::Free(tls_index_);
+ tls_index_ = -1;
status_ = UNINITIALIZED;
}