summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-20 21:47:40 +0000
committerevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-20 21:47:40 +0000
commitc3ec35638ea6594b6bdbac7ff92c38add8984623 (patch)
treec51541ac2451e66c410b3d244e1f59ac2218c57e
parente537c3515e270527ba2fa54fcfc4a1ed49cc975e (diff)
downloadchromium_src-c3ec35638ea6594b6bdbac7ff92c38add8984623.zip
chromium_src-c3ec35638ea6594b6bdbac7ff92c38add8984623.tar.gz
chromium_src-c3ec35638ea6594b6bdbac7ff92c38add8984623.tar.bz2
TrackedObjects assumes you can use a "TLS slot" of -1 to indicate uninitialized. This isn't true for the pthread_key_t type, which is unsigned on Linux and reportedly a struct on Macs. This change modifies the Slot type to be a struct containing an "initialized" flag.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1113 0039d316-1c4b-4281-b951-d872f2087c98
-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
-rw-r--r--chrome/common/ipc_sync_channel.cc12
-rw-r--r--chrome/common/notification_service.cc10
-rw-r--r--chrome/common/notification_service.h7
-rw-r--r--chrome/common/rand_util.cc7
-rw-r--r--chrome/renderer/render_thread.cc8
-rw-r--r--chrome/renderer/render_thread.h4
-rw-r--r--webkit/glue/plugins/plugin_instance.cc15
-rw-r--r--webkit/glue/plugins/plugin_instance.h3
16 files changed, 170 insertions, 121 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_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_;