diff options
-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_unittest.cc | 16 | ||||
-rw-r--r-- | base/thread_local_storage_win.cc | 53 | ||||
-rw-r--r-- | base/tracked_objects.cc | 25 | ||||
-rw-r--r-- | chrome/common/ipc_sync_channel.cc | 12 | ||||
-rw-r--r-- | chrome/common/notification_service.cc | 10 | ||||
-rw-r--r-- | chrome/common/notification_service.h | 7 | ||||
-rw-r--r-- | chrome/common/rand_util.cc | 7 | ||||
-rw-r--r-- | chrome/renderer/render_thread.cc | 8 | ||||
-rw-r--r-- | chrome/renderer/render_thread.h | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_instance.cc | 15 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_instance.h | 3 |
17 files changed, 178 insertions, 129 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc index caec847..bdf99f0 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -39,7 +39,9 @@ // 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. -/*static*/ TLSSlot MessageLoop::tls_index_ = ThreadLocalStorage::Alloc(); +// TODO(evanm): this shouldn't rely on static initialization. +// static +TLSSlot MessageLoop::tls_index_; //------------------------------------------------------------------------------ @@ -83,7 +85,7 @@ MessageLoop::MessageLoop() exception_restoration_(false), state_(NULL) { DCHECK(!current()) << "should only have one message loop per thread"; - ThreadLocalStorage::Set(tls_index_, this); + tls_index_.Set(this); // TODO(darin): Generalize this to support instantiating different pumps. #if defined(OS_WIN) pump_ = new base::MessagePumpWin(); @@ -100,7 +102,7 @@ MessageLoop::~MessageLoop() { WillDestroyCurrentMessageLoop()); // OK, now make it so that no one can find us. - ThreadLocalStorage::Set(tls_index_, NULL); + tls_index_.Set(NULL); DCHECK(!state_); diff --git a/base/message_loop.h b/base/message_loop.h index 3821519..e11b73f 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*>(ThreadLocalStorage::Get(tls_index_)); + return static_cast<MessageLoop*>(tls_index_.Get()); } // Returns the TimerManager object for the current thread. diff --git a/base/stats_table.cc b/base/stats_table.cc index 23c736a..8b10662 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_(ThreadLocalStorage::Alloc(SlotReturnFunction)) { + : tls_index_(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. - ThreadLocalStorage::Free(tls_index_); + tls_index_.Free(); // 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; - ThreadLocalStorage::Set(tls_index_, data); + tls_index_.Set(data); return slot; } StatsTableTLSData* StatsTable::GetTLSData() const { StatsTableTLSData* data = - static_cast<StatsTableTLSData*>(ThreadLocalStorage::Get(tls_index_)); + static_cast<StatsTableTLSData*>(tls_index_.Get()); 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. - ThreadLocalStorage::Set(tls_index_, NULL); + tls_index_.Set(NULL); delete data; } diff --git a/base/thread.cc b/base/thread.cc index 629c7e0..6998deb 100644 --- a/base/thread.cc +++ b/base/thread.cc @@ -69,7 +69,6 @@ Thread::Thread(const char *name) thread_id_(0), message_loop_(NULL), name_(name) { - DCHECK(tls_index_) << "static initializer failed"; } Thread::~Thread() { @@ -82,18 +81,19 @@ 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. -TLSSlot Thread::tls_index_ = ThreadLocalStorage::Alloc(); +// TODO(evanm): this shouldn't rely on static initialization. +TLSSlot Thread::tls_index_; void Thread::SetThreadWasQuitProperly(bool flag) { #ifndef NDEBUG - ThreadLocalStorage::Set(tls_index_, reinterpret_cast<void*>(flag)); + tls_index_.Set(reinterpret_cast<void*>(flag)); #endif } bool Thread::GetThreadWasQuitProperly() { bool quit_properly = true; #ifndef NDEBUG - quit_properly = (ThreadLocalStorage::Get(tls_index_) != 0); + quit_properly = (tls_index_.Get() != 0); #endif return quit_properly; } diff --git a/base/thread_local_storage.h b/base/thread_local_storage.h index 245a73f..fba90ae 100644 --- a/base/thread_local_storage.h +++ b/base/thread_local_storage.h @@ -32,43 +32,62 @@ #include "base/basictypes.h" -#if defined(OS_WIN) -typedef int TLSSlot; -#elif defined(OS_POSIX) +#if defined(OS_POSIX) #include <pthread.h> -typedef pthread_key_t TLSSlot; -#endif // OS_* +#endif -// Wrapper for thread local storage. This class doesn't -// do much except provide an API for portability later. +// Wrapper for thread local storage. This class doesn't do much except provide +// an API for portability. 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); - // 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); + // 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(); - // 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); + // Get the thread-local value stored in slot 'slot'. + // Values are guaranteed to initially be zero. + void* Get() const; - // Get the thread-local value stored in slot 'slot'. - // Values are guaranteed to initially be zero. - static void* Get(TLSSlot slot); + // Set the thread-local value stored in slot 'slot' to + // value 'value'. + void Set(void* value); - // Set the thread-local value stored in slot 'slot' to - // value 'value'. - static void Set(TLSSlot slot, void* value); + 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); + }; #if defined(OS_WIN) // Function called when on thread exit to call TLS @@ -90,7 +109,11 @@ class ThreadLocalStorage { static TLSDestructorFunc tls_destructors_[kThreadLocalStorageSize]; #endif // OS_WIN - DISALLOW_EVIL_CONSTRUCTORS(ThreadLocalStorage); + DISALLOW_COPY_AND_ASSIGN(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 bcc982f..7c24e59 100644 --- a/base/thread_local_storage_posix.cc +++ b/base/thread_local_storage_posix.cc @@ -31,23 +31,39 @@ #include "base/logging.h" -TLSSlot ThreadLocalStorage::Alloc(TLSDestructorFunc destructor) { - TLSSlot key; - int error = pthread_key_create(&key, destructor); - if (error) +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) { NOTREACHED(); + return false; + } - return key; + initialized_ = true; + return true; } -void ThreadLocalStorage::Free(TLSSlot slot) { - pthread_key_delete(slot); +void ThreadLocalStorage::Slot::Free() { + DCHECK(initialized_); + int error = pthread_key_delete(key_); + if (error) + NOTREACHED(); + initialized_ = false; } -void* ThreadLocalStorage::Get(TLSSlot slot) { - return pthread_getspecific(slot); +void* ThreadLocalStorage::Slot::Get() const { + DCHECK(initialized_); + return pthread_getspecific(key_); } -void ThreadLocalStorage::Set(TLSSlot slot, void* value) { - pthread_setspecific(slot, value); +void ThreadLocalStorage::Slot::Set(void* value) { + DCHECK(initialized_); + int error = pthread_setspecific(key_, value); + if (error) + NOTREACHED(); } diff --git a/base/thread_local_storage_unittest.cc b/base/thread_local_storage_unittest.cc index fff0d2a..ba60c2c 100644 --- a/base/thread_local_storage_unittest.cc +++ b/base/thread_local_storage_unittest.cc @@ -44,28 +44,28 @@ namespace { TEST(ThreadLocalStorageTest, Basics) { - int index = ThreadLocalStorage::Alloc(); - ThreadLocalStorage::Set(index, reinterpret_cast<void*>(123)); - int value = reinterpret_cast<int>(ThreadLocalStorage::Get(index)); + ThreadLocalStorage::Slot slot; + slot.Set(reinterpret_cast<void*>(123)); + int value = reinterpret_cast<int>(slot.Get()); EXPECT_EQ(value, 123); } const int kInitialTlsValue = 0x5555; -static int tls_index = 0; +static ThreadLocalStorage::Slot tls_slot(base::LINKER_INITIALIZED); unsigned __stdcall TLSTestThreadMain(void* param) { // param contains the thread local storage index. int *index = reinterpret_cast<int*>(param); *index = kInitialTlsValue; - ThreadLocalStorage::Set(tls_index, index); + tls_slot.Set(index); - int *ptr = static_cast<int*>(ThreadLocalStorage::Get(tls_index)); + int *ptr = static_cast<int*>(tls_slot.Get()); EXPECT_EQ(ptr, index); EXPECT_EQ(*ptr, kInitialTlsValue); *index = 0; - ptr = static_cast<int*>(ThreadLocalStorage::Get(tls_index)); + ptr = static_cast<int*>(tls_slot.Get()); EXPECT_EQ(ptr, index); EXPECT_EQ(*ptr, 0); return 0; @@ -86,7 +86,7 @@ TEST(ThreadLocalStorageTest, TLSDestructors) { HANDLE threads[kNumThreads]; int values[kNumThreads]; - tls_index = ThreadLocalStorage::Alloc(ThreadLocalStorageCleanup); + tls_slot.Initialize(ThreadLocalStorageCleanup); // Spawn the threads. for (int16 index = 0; index < kNumThreads; index++) { diff --git a/base/thread_local_storage_win.cc b/base/thread_local_storage_win.cc index 8157e88..154935a 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,52 +73,59 @@ 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; } -TLSSlot ThreadLocalStorage::Alloc(TLSDestructorFunc destructor) { +ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor) + : initialized_(false) { + Initialize(destructor); +} + +bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) { if (tls_key_ == TLS_OUT_OF_INDEXES || !TlsGetValue(tls_key_)) - Initialize(); + ThreadLocalStorage::Initialize(); // Grab a new slot. - int slot = InterlockedIncrement(&tls_max_) - 1; - if (slot >= kThreadLocalStorageSize) { + slot_ = InterlockedIncrement(&tls_max_) - 1; + if (slot_ >= kThreadLocalStorageSize) { NOTREACHED(); - return -1; + return false; } // Setup our destructor. - tls_destructors_[slot] = destructor; - return slot; + tls_destructors_[slot_] = destructor; + initialized_ = true; + return true; } -void ThreadLocalStorage::Free(TLSSlot slot) { +void ThreadLocalStorage::Slot::Free() { // 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; + tls_destructors_[slot_] = NULL; + initialized_ = false; } -void* ThreadLocalStorage::Get(TLSSlot slot) { - void **tls_data = static_cast<void**>(TlsGetValue(tls_key_)); +void* ThreadLocalStorage::Slot::Get() const { + void** tls_data = static_cast<void**>(TlsGetValue(tls_key_)); if (!tls_data) - tls_data = Initialize(); - DCHECK(slot >= 0 && slot < kThreadLocalStorageSize); - return tls_data[slot]; + tls_data = ThreadLocalStorage::Initialize(); + DCHECK(slot_ >= 0 && slot_ < kThreadLocalStorageSize); + return tls_data[slot_]; } -void ThreadLocalStorage::Set(TLSSlot slot, void* value) { - void **tls_data = static_cast<void**>(TlsGetValue(tls_key_)); +void ThreadLocalStorage::Slot::Set(void* value) { + void** tls_data = static_cast<void**>(TlsGetValue(tls_key_)); if (!tls_data) - tls_data = Initialize(); - DCHECK(slot >= 0 && slot < kThreadLocalStorageSize); - tls_data[slot] = value; + tls_data = ThreadLocalStorage::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) @@ -126,7 +133,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 b683a87..83a7fbd 100644 --- a/base/tracked_objects.cc +++ b/base/tracked_objects.cc @@ -35,9 +35,9 @@ namespace tracked_objects { -// a TLS index to the TrackRegistry for the current thread. +// A TLS slot to the TrackRegistry for the current thread. // static -TLSSlot ThreadData::tls_index_ = -1; +TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); //------------------------------------------------------------------------------ // Death data tallies durations when a death takes place. @@ -104,15 +104,14 @@ 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 (-1 == tls_index_) - return NULL; // not yet initialized. + if (!tls_index_.initialized()) + return NULL; - ThreadData* registry = - static_cast<ThreadData*>(ThreadLocalStorage::Get(tls_index_)); + ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get()); if (!registry) { // We have to create a new registry for ThreadData. bool too_late_to_create = false; @@ -132,7 +131,7 @@ ThreadData* ThreadData::current() { delete registry; registry = NULL; } else { - ThreadLocalStorage::Set(tls_index_, registry); + tls_index_.Set(registry); } } return registry; @@ -344,11 +343,9 @@ bool ThreadData::StartTracking(bool status) { status_ = SHUTDOWN; return true; } - TLSSlot tls_index = ThreadLocalStorage::Alloc(); AutoLock lock(list_lock_); DCHECK(status_ == UNINITIALIZED); - tls_index_ = tls_index; - CHECK(-1 != tls_index_); + CHECK(tls_index_.Initialize(NULL)); status_ = ACTIVE; return true; } @@ -401,9 +398,9 @@ void ThreadData::ShutdownSingleThreadedCleanup() { delete next_thread_data; // Includes all Death Records. } - CHECK(-1 != tls_index_); - ThreadLocalStorage::Free(tls_index_); - tls_index_ = -1; + CHECK(tls_index_.initialized()); + tls_index_.Free(); + DCHECK(!tls_index_.initialized()); status_ = UNINITIALIZED; } diff --git a/chrome/common/ipc_sync_channel.cc b/chrome/common/ipc_sync_channel.cc index 25a22c8..3932c6d 100644 --- a/chrome/common/ipc_sync_channel.cc +++ b/chrome/common/ipc_sync_channel.cc @@ -57,7 +57,8 @@ namespace IPC { // sync message while another one is blocked). // Holds a pointer to the per-thread ReceivedSyncMsgQueue object. -static int g_tls_index = ThreadLocalStorage::Alloc(); +// TODO(evanm): this shouldn't rely on static initialization. +static TLSSlot g_tls_index; class SyncChannel::ReceivedSyncMsgQueue : public base::RefCountedThreadSafe<ReceivedSyncMsgQueue> { @@ -69,10 +70,10 @@ class SyncChannel::ReceivedSyncMsgQueue : } ~ReceivedSyncMsgQueue() { - DCHECK(ThreadLocalStorage::Get(g_tls_index)); + DCHECK(g_tls_index.Get()); DCHECK(MessageLoop::current() == listener_message_loop_); CloseHandle(blocking_event_); - ThreadLocalStorage::Set(g_tls_index, NULL); + g_tls_index.Set(NULL); } // Called on IPC thread when a synchronous message or reply arrives. @@ -237,14 +238,13 @@ SyncChannel::SyncContext::SyncContext( reply_deserialize_result_(false) { // We want one ReceivedSyncMsgQueue per listener thread (i.e. since multiple // SyncChannel objects that can block the same thread). - received_sync_msgs_ = static_cast<ReceivedSyncMsgQueue*>( - ThreadLocalStorage::Get(g_tls_index)); + received_sync_msgs_ = static_cast<ReceivedSyncMsgQueue*>(g_tls_index.Get()); if (!received_sync_msgs_) { // Stash a pointer to the listener thread's ReceivedSyncMsgQueue, as we // need to be able to access it in the IPC thread. received_sync_msgs_ = new ReceivedSyncMsgQueue(); - ThreadLocalStorage::Set(g_tls_index, received_sync_msgs_); + g_tls_index.Set(received_sync_msgs_); } // Addref manually so that we can ensure destruction on the listener thread diff --git a/chrome/common/notification_service.cc b/chrome/common/notification_service.cc index 672052f..2345ba0 100644 --- a/chrome/common/notification_service.cc +++ b/chrome/common/notification_service.cc @@ -29,9 +29,11 @@ #include "chrome/common/notification_service.h" -int NotificationService::tls_index_ = ThreadLocalStorage::Alloc(); +// TODO(evanm): This shouldn't depend on static initialization. +// static +TLSSlot NotificationService::tls_index_; -/* static */ +// static bool NotificationService::HasKey(const NotificationSourceMap& map, const NotificationSource& source) { return map.find(source.map_key()) != map.end(); @@ -43,7 +45,7 @@ NotificationService::NotificationService() { memset(observer_counts_, 0, sizeof(observer_counts_)); #endif - ThreadLocalStorage::Set(tls_index_, this); + tls_index_.Set(this); } void NotificationService::AddObserver(NotificationObserver* observer, @@ -117,7 +119,7 @@ void NotificationService::Notify(NotificationType type, NotificationService::~NotificationService() { - ThreadLocalStorage::Set(tls_index_, NULL); + tls_index_.Set(NULL); #ifndef NDEBUG for (int i = 0; i < NOTIFICATION_TYPE_COUNT; i++) { diff --git a/chrome/common/notification_service.h b/chrome/common/notification_service.h index 1243748..6ad58d0 100644 --- a/chrome/common/notification_service.h +++ b/chrome/common/notification_service.h @@ -36,8 +36,8 @@ #include <map> -#include "base/thread_local_storage.h" #include "base/observer_list.h" +#include "base/thread_local_storage.h" #include "base/values.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_source.h" @@ -50,8 +50,7 @@ class NotificationService { // Returns the NotificationService object for the current thread, or NULL if // none. static NotificationService* current() { - return static_cast<NotificationService *>( - ThreadLocalStorage::Get(tls_index_)); + return static_cast<NotificationService *>(tls_index_.Get()); } // Normally instantiated when the thread is created. Not all threads have @@ -119,7 +118,7 @@ class NotificationService { // The thread local storage index, used for getting the current thread's // instance. - static int tls_index_; + static TLSSlot tls_index_; #ifndef NDEBUG // Used to check to see that AddObserver and RemoveObserver calls are diff --git a/chrome/common/rand_util.cc b/chrome/common/rand_util.cc index 13c586f..d6c2824 100644 --- a/chrome/common/rand_util.cc +++ b/chrome/common/rand_util.cc @@ -39,12 +39,13 @@ namespace rand_util { +// TODO(evanm): don't rely on static initialization. // Using TLS since srand() needs to be called once in each thread. -int g_tls_index = ThreadLocalStorage::Alloc(); +TLSSlot g_tls_index; int RandInt(int min, int max) { - if (ThreadLocalStorage::Get(g_tls_index) == 0) { - ThreadLocalStorage::Set(g_tls_index, reinterpret_cast<void*>(1)); + if (g_tls_index.Get() == 0) { + g_tls_index.Set(reinterpret_cast<void*>(1)); TimeDelta now = TimeTicks::UnreliableHighResNow() - TimeTicks(); unsigned int seed = static_cast<unsigned int>(now.InMicroseconds()); srand(seed); diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index b37cf454..14f9313 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -47,8 +47,9 @@ static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */; // V8 needs a 1MB stack size. static const size_t kStackSize = 1024 * 1024; -/*static*/ -DWORD RenderThread::tls_index_ = ThreadLocalStorage::Alloc(); +// TODO(evanm): don't rely on static initialization. +// static +TLSSlot RenderThread::tls_index_; //----------------------------------------------------------------------------- // Methods below are only called on the owner's thread: @@ -106,7 +107,6 @@ void RenderThread::RemoveRoute(int32 routing_id) { } void RenderThread::Init() { - DCHECK(tls_index_) << "static initializer failed"; DCHECK(!current()) << "should only have one RenderThread per thread"; notification_service_.reset(new NotificationService); @@ -118,7 +118,7 @@ void RenderThread::Init() { IPC::Channel::MODE_CLIENT, this, NULL, owner_loop_, true, RenderProcess::GetShutDownEvent())); - ThreadLocalStorage::Set(tls_index_, this); + tls_index_.Set(this); // The renderer thread should wind-up COM. CoInitialize(0); diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 9463a20..5e4f336 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -74,7 +74,7 @@ class RenderThread : public IPC::Channel::Listener, // The RenderThread instance for the current thread. static RenderThread* current() { - return static_cast<RenderThread*>(ThreadLocalStorage::Get(tls_index_)); + return static_cast<RenderThread*>(tls_index_.Get()); } VisitedLinkSlave* visited_link_slave() const { return visited_link_slave_; } @@ -119,7 +119,7 @@ class RenderThread : public IPC::Channel::Listener, // decisions about how to allocation resources using current information. void InformHostOfCacheStats(); - static DWORD tls_index_; + static TLSSlot tls_index_; // The message loop used to run tasks on the thread that started this thread. MessageLoop* owner_loop_; diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc index 62e1357..405acb5 100644 --- a/webkit/glue/plugins/plugin_instance.cc +++ b/webkit/glue/plugins/plugin_instance.cc @@ -45,7 +45,9 @@ namespace NPAPI { -int PluginInstance::plugin_instance_tls_index_ = ThreadLocalStorage::Alloc(); + +// TODO(evanm): don't rely on static initialization. +ThreadLocalStorage::Slot PluginInstance::plugin_instance_tls_index_; PluginInstance::PluginInstance(PluginLib *plugin, const std::string &mime_type) : plugin_(plugin), @@ -429,17 +431,16 @@ void PluginInstance::OnPluginThreadAsyncCall(void (*func)(void *), PluginInstance* PluginInstance::SetInitializingInstance( PluginInstance* instance) { PluginInstance* old_instance = - static_cast<PluginInstance*>( - ThreadLocalStorage::Get(plugin_instance_tls_index_)); - ThreadLocalStorage::Set(plugin_instance_tls_index_, instance); + static_cast<PluginInstance*>(plugin_instance_tls_index_.Get()); + plugin_instance_tls_index_.Set(instance); return old_instance; } PluginInstance* PluginInstance::GetInitializingInstance() { PluginInstance* instance = - static_cast<PluginInstance*>( - ThreadLocalStorage::Get(plugin_instance_tls_index_)); - return instance;} + static_cast<PluginInstance*>(plugin_instance_tls_index_.Get()); + return instance; +} NPError PluginInstance::GetServiceManager(void** service_manager) { if (!mozilla_extenstions_) { diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h index 5743c24..6cbfd5a 100644 --- a/webkit/glue/plugins/plugin_instance.h +++ b/webkit/glue/plugins/plugin_instance.h @@ -40,6 +40,7 @@ #include "base/basictypes.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" +#include "base/thread_local_storage.h" #include "webkit/glue/plugins/nphostapi.h" #include "googleurl/src/gurl.h" #include "third_party/npapi/bindings/npapi.h" @@ -261,7 +262,7 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // We need to pass this instance to the service manager // (MozillaExtensionApi) created as a result of NPN_GetValue // in the context of NP_Initialize. - static int plugin_instance_tls_index_; + static ThreadLocalStorage::Slot plugin_instance_tls_index_; scoped_refptr<PluginDataStream> plugin_data_stream_; GURL instance_url_; |