diff options
author | evanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-20 22:11:47 +0000 |
---|---|---|
committer | evanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-20 22:11:47 +0000 |
commit | fa87a2527ca8c0bcef92d8e44791332782936911 (patch) | |
tree | 04dc5d1e6881f8356f91203a386648057b20d924 /base | |
parent | 4f64d0af5908e36d356c834005d08cca98d579fe (diff) | |
download | chromium_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.cc | 8 | ||||
-rw-r--r-- | base/message_loop.h | 2 | ||||
-rw-r--r-- | base/stats_table.cc | 10 | ||||
-rw-r--r-- | base/thread.cc | 8 | ||||
-rw-r--r-- | base/thread_local_storage.h | 81 | ||||
-rw-r--r-- | base/thread_local_storage_posix.cc | 38 | ||||
-rw-r--r-- | base/thread_local_storage_win.cc | 53 | ||||
-rw-r--r-- | base/tracked_objects.cc | 25 |
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; } |