diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-30 16:52:09 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-30 16:52:09 +0000 |
commit | 444b8a3c2cb9f74a280eb370abd8792d51870dcb (patch) | |
tree | 37be62fef7f7a45a1e93dee5e898e5d25aa40962 /base/threading | |
parent | 0d4cd065a9b3e28de6ae1e332e1b5fe1d38d6cb6 (diff) | |
download | chromium_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.h | 38 | ||||
-rw-r--r-- | base/threading/thread_local_storage_posix.cc | 16 | ||||
-rw-r--r-- | base/threading/thread_local_storage_unittest.cc | 4 | ||||
-rw-r--r-- | base/threading/thread_local_storage_win.cc | 16 |
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(); |