summaryrefslogtreecommitdiffstats
path: root/base/threading
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 /base/threading
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
Diffstat (limited to 'base/threading')
-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
4 files changed, 46 insertions, 28 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();