summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-30 16:52:09 +0000
committerthakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-30 16:52:09 +0000
commit444b8a3c2cb9f74a280eb370abd8792d51870dcb (patch)
tree37be62fef7f7a45a1e93dee5e898e5d25aa40962
parent0d4cd065a9b3e28de6ae1e332e1b5fe1d38d6cb6 (diff)
downloadchromium_src-444b8a3c2cb9f74a280eb370abd8792d51870dcb.zip
chromium_src-444b8a3c2cb9f74a280eb370abd8792d51870dcb.tar.gz
chromium_src-444b8a3c2cb9f74a280eb370abd8792d51870dcb.tar.bz2
Make it possible to use ThreadLocalStorage::Slot as a static without
introducing static initializers. Member variables can stay TLS::Slots and their behavior doesn't change. Static instances use TLS::StaticSlot instead. Kind of like http://codereview.chromium.org/8491043 but for TLS. BUG=none TEST=none TBR=agl Review URL: https://chromiumcodereview.appspot.com/9297010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119679 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/threading/thread_local_storage.h38
-rw-r--r--base/threading/thread_local_storage_posix.cc16
-rw-r--r--base/threading/thread_local_storage_unittest.cc4
-rw-r--r--base/threading/thread_local_storage_win.cc16
-rw-r--r--base/tracked_objects.cc2
-rw-r--r--base/tracked_objects.h2
-rw-r--r--net/base/dns_reloader.cc5
-rw-r--r--ppapi/proxy/ppb_message_loop_proxy.cc2
8 files changed, 51 insertions, 34 deletions
diff --git a/base/threading/thread_local_storage.h b/base/threading/thread_local_storage.h
index 214b7e1..30cbd47 100644
--- a/base/threading/thread_local_storage.h
+++ b/base/threading/thread_local_storage.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -25,15 +25,18 @@ class BASE_EXPORT ThreadLocalStorage {
// stored in thread local storage.
typedef void (*TLSDestructorFunc)(void* value);
- // A key representing one value stored in TLS.
- class BASE_EXPORT Slot {
- public:
- explicit Slot(TLSDestructorFunc destructor = NULL);
-
- // This constructor should be used for statics.
- // It returns an uninitialized Slot.
- explicit Slot(base::LinkerInitialized x) {}
+ // StaticSlot uses its own struct initializer-list style static
+ // initialization, as base's LINKER_INITIALIZED requires a constructor and on
+ // some compilers (notably gcc 4.4) this still ends up needing runtime
+ // initialization.
+ #define TLS_INITIALIZER {0}
+ // A key representing one value stored in TLS.
+ // Initialize like
+ // ThreadLocalStorage::StaticSlot my_slot = TLS_INITIALIZER;
+ // If you're not using a static variable, use the convenience class
+ // ThreadLocalStorage::Slot (below) instead.
+ struct BASE_EXPORT StaticSlot {
// 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.
@@ -56,7 +59,6 @@ class BASE_EXPORT ThreadLocalStorage {
bool initialized() const { return initialized_; }
- private:
// The internals of this struct should be considered private.
bool initialized_;
#if defined(OS_WIN)
@@ -65,6 +67,22 @@ class BASE_EXPORT ThreadLocalStorage {
pthread_key_t key_;
#endif
+ };
+
+ // A convenience wrapper around StaticSlot with a constructor. Can be used
+ // as a member variable.
+ class BASE_EXPORT Slot : public StaticSlot {
+ public:
+ // Calls StaticSlot::Initialize().
+ explicit Slot(TLSDestructorFunc destructor = NULL);
+
+ private:
+ using StaticSlot::initialized_;
+#if defined(OS_WIN)
+ using StaticSlot::slot_;
+#elif defined(OS_POSIX)
+ using StaticSlot::key_;
+#endif
DISALLOW_COPY_AND_ASSIGN(Slot);
};
diff --git a/base/threading/thread_local_storage_posix.cc b/base/threading/thread_local_storage_posix.cc
index 3d0e187..75da5a7 100644
--- a/base/threading/thread_local_storage_posix.cc
+++ b/base/threading/thread_local_storage_posix.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -8,13 +8,13 @@
namespace base {
-ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor)
- : initialized_(false),
- key_(0) {
+ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor) {
+ initialized_ = false;
+ key_ = 0;
Initialize(destructor);
}
-bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) {
+bool ThreadLocalStorage::StaticSlot::Initialize(TLSDestructorFunc destructor) {
DCHECK(!initialized_);
int error = pthread_key_create(&key_, destructor);
if (error) {
@@ -26,7 +26,7 @@ bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) {
return true;
}
-void ThreadLocalStorage::Slot::Free() {
+void ThreadLocalStorage::StaticSlot::Free() {
DCHECK(initialized_);
int error = pthread_key_delete(key_);
if (error)
@@ -34,12 +34,12 @@ void ThreadLocalStorage::Slot::Free() {
initialized_ = false;
}
-void* ThreadLocalStorage::Slot::Get() const {
+void* ThreadLocalStorage::StaticSlot::Get() const {
DCHECK(initialized_);
return pthread_getspecific(key_);
}
-void ThreadLocalStorage::Slot::Set(void* value) {
+void ThreadLocalStorage::StaticSlot::Set(void* value) {
DCHECK(initialized_);
int error = pthread_setspecific(key_, value);
if (error)
diff --git a/base/threading/thread_local_storage_unittest.cc b/base/threading/thread_local_storage_unittest.cc
index 33db1b0..0a6ba6b 100644
--- a/base/threading/thread_local_storage_unittest.cc
+++ b/base/threading/thread_local_storage_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -26,7 +26,7 @@ const int kFinalTlsValue = 0x7777;
// How many times must a destructor be called before we really are done.
const int kNumberDestructorCallRepetitions = 3;
-static ThreadLocalStorage::Slot tls_slot(LINKER_INITIALIZED);
+static ThreadLocalStorage::StaticSlot tls_slot = TLS_INITIALIZER;
class ThreadLocalStorageRunner : public DelegateSimpleThread::Delegate {
public:
diff --git a/base/threading/thread_local_storage_win.cc b/base/threading/thread_local_storage_win.cc
index badadb8..db66248 100644
--- a/base/threading/thread_local_storage_win.cc
+++ b/base/threading/thread_local_storage_win.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -86,13 +86,13 @@ void** ThreadLocalStorage::Initialize() {
return tls_data;
}
-ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor)
- : initialized_(false),
- slot_(0) {
+ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor) {
+ initialized_ = false;
+ slot_ = 0;
Initialize(destructor);
}
-bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) {
+bool ThreadLocalStorage::StaticSlot::Initialize(TLSDestructorFunc destructor) {
if (tls_key_ == TLS_OUT_OF_INDEXES || !TlsGetValue(tls_key_))
ThreadLocalStorage::Initialize();
@@ -110,7 +110,7 @@ bool ThreadLocalStorage::Slot::Initialize(TLSDestructorFunc destructor) {
return true;
}
-void ThreadLocalStorage::Slot::Free() {
+void ThreadLocalStorage::StaticSlot::Free() {
// At this time, we don't reclaim old indices for TLS slots.
// So all we need to do is wipe the destructor.
DCHECK_GT(slot_, 0);
@@ -120,7 +120,7 @@ void ThreadLocalStorage::Slot::Free() {
initialized_ = false;
}
-void* ThreadLocalStorage::Slot::Get() const {
+void* ThreadLocalStorage::StaticSlot::Get() const {
void** tls_data = static_cast<void**>(TlsGetValue(tls_key_));
if (!tls_data)
tls_data = ThreadLocalStorage::Initialize();
@@ -129,7 +129,7 @@ void* ThreadLocalStorage::Slot::Get() const {
return tls_data[slot_];
}
-void ThreadLocalStorage::Slot::Set(void* value) {
+void ThreadLocalStorage::StaticSlot::Set(void* value) {
void** tls_data = static_cast<void**>(TlsGetValue(tls_key_));
if (!tls_data)
tls_data = ThreadLocalStorage::Initialize();
diff --git a/base/tracked_objects.cc b/base/tracked_objects.cc
index 71b3bc6..e7d7bd1 100644
--- a/base/tracked_objects.cc
+++ b/base/tracked_objects.cc
@@ -180,7 +180,7 @@ void Births::Clear() { birth_count_ = 0; }
// do a fake initialization here (zeroing out data), and then the real in-place
// construction happens when we call tls_index_.Initialize().
// static
-base::ThreadLocalStorage::Slot ThreadData::tls_index_(base::LINKER_INITIALIZED);
+base::ThreadLocalStorage::StaticSlot ThreadData::tls_index_ = TLS_INITIALIZER;
// static
int ThreadData::worker_thread_data_creation_count_ = 0;
diff --git a/base/tracked_objects.h b/base/tracked_objects.h
index b1bf02e..9b7f111 100644
--- a/base/tracked_objects.h
+++ b/base/tracked_objects.h
@@ -544,7 +544,7 @@ class BASE_EXPORT ThreadData {
static void ShutdownSingleThreadedCleanup(bool leak);
// We use thread local store to identify which ThreadData to interact with.
- static base::ThreadLocalStorage::Slot tls_index_;
+ static base::ThreadLocalStorage::StaticSlot tls_index_;
// List of ThreadData instances for use with worker threads. When a worker
// thread is done (terminated), we push it onto this llist. When a new worker
diff --git a/net/base/dns_reloader.cc b/net/base/dns_reloader.cc
index ff79388..2254f9a 100644
--- a/net/base/dns_reloader.cc
+++ b/net/base/dns_reloader.cc
@@ -93,15 +93,14 @@ class DnsReloader : public net::NetworkChangeNotifier::DNSObserver {
friend struct base::DefaultLazyInstanceTraits<DnsReloader>;
// We use thread local storage to identify which ReloadState to interact with.
- static base::ThreadLocalStorage::Slot tls_index_ ;
+ static base::ThreadLocalStorage::StaticSlot tls_index_;
DISALLOW_COPY_AND_ASSIGN(DnsReloader);
};
// A TLS slot to the ReloadState for the current thread.
// static
-base::ThreadLocalStorage::Slot DnsReloader::tls_index_(
- base::LINKER_INITIALIZED);
+base::ThreadLocalStorage::StaticSlot DnsReloader::tls_index_ = TLS_INITIALIZER;
base::LazyInstance<DnsReloader>::Leaky
g_dns_reloader = LAZY_INSTANCE_INITIALIZER;
diff --git a/ppapi/proxy/ppb_message_loop_proxy.cc b/ppapi/proxy/ppb_message_loop_proxy.cc
index 5a0cf23..75f9c86 100644
--- a/ppapi/proxy/ppb_message_loop_proxy.cc
+++ b/ppapi/proxy/ppb_message_loop_proxy.cc
@@ -26,7 +26,7 @@ namespace {
typedef thunk::EnterResource<PPB_MessageLoop_API> EnterMessageLoop;
-static base::ThreadLocalStorage::Slot tls_slot(base::LINKER_INITIALIZED);
+static base::ThreadLocalStorage::StaticSlot tls_slot = TLS_INITIALIZER;
class MessageLoopResource : public Resource, public PPB_MessageLoop_API {
public: