michael@0: // Copyright (c) 2012 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #ifndef BASE_THREADING_THREAD_LOCAL_STORAGE_H_ michael@0: #define BASE_THREADING_THREAD_LOCAL_STORAGE_H_ michael@0: michael@0: #include "base/base_export.h" michael@0: #include "base/basictypes.h" michael@0: michael@0: #if defined(OS_POSIX) michael@0: #include michael@0: #endif michael@0: michael@0: namespace base { michael@0: michael@0: // Wrapper for thread local storage. This class doesn't do much except provide michael@0: // an API for portability. michael@0: class BASE_EXPORT ThreadLocalStorage { michael@0: public: michael@0: michael@0: // Prototype for the TLS destructor function, which can be optionally used to michael@0: // cleanup thread local storage on thread exit. 'value' is the data that is michael@0: // stored in thread local storage. michael@0: typedef void (*TLSDestructorFunc)(void* value); michael@0: michael@0: // StaticSlot uses its own struct initializer-list style static michael@0: // initialization, as base's LINKER_INITIALIZED requires a constructor and on michael@0: // some compilers (notably gcc 4.4) this still ends up needing runtime michael@0: // initialization. michael@0: #define TLS_INITIALIZER {0} michael@0: michael@0: // A key representing one value stored in TLS. michael@0: // Initialize like michael@0: // ThreadLocalStorage::StaticSlot my_slot = TLS_INITIALIZER; michael@0: // If you're not using a static variable, use the convenience class michael@0: // ThreadLocalStorage::Slot (below) instead. michael@0: struct BASE_EXPORT StaticSlot { michael@0: // Set up the TLS slot. Called by the constructor. michael@0: // 'destructor' is a pointer to a function to perform per-thread cleanup of michael@0: // this object. If set to NULL, no cleanup is done for this TLS slot. michael@0: // Returns false on error. michael@0: bool Initialize(TLSDestructorFunc destructor); michael@0: michael@0: // Free a previously allocated TLS 'slot'. michael@0: // If a destructor was set for this slot, removes michael@0: // the destructor so that remaining threads exiting michael@0: // will not free data. michael@0: void Free(); michael@0: michael@0: // Get the thread-local value stored in slot 'slot'. michael@0: // Values are guaranteed to initially be zero. michael@0: void* Get() const; michael@0: michael@0: // Set the thread-local value stored in slot 'slot' to michael@0: // value 'value'. michael@0: void Set(void* value); michael@0: michael@0: bool initialized() const { return initialized_; } michael@0: michael@0: // The internals of this struct should be considered private. michael@0: bool initialized_; michael@0: #if defined(OS_WIN) michael@0: int slot_; michael@0: #elif defined(OS_POSIX) michael@0: pthread_key_t key_; michael@0: #endif michael@0: michael@0: }; michael@0: michael@0: // A convenience wrapper around StaticSlot with a constructor. Can be used michael@0: // as a member variable. michael@0: class BASE_EXPORT Slot : public StaticSlot { michael@0: public: michael@0: // Calls StaticSlot::Initialize(). michael@0: explicit Slot(TLSDestructorFunc destructor = NULL); michael@0: michael@0: private: michael@0: using StaticSlot::initialized_; michael@0: #if defined(OS_WIN) michael@0: using StaticSlot::slot_; michael@0: #elif defined(OS_POSIX) michael@0: using StaticSlot::key_; michael@0: #endif michael@0: DISALLOW_COPY_AND_ASSIGN(Slot); michael@0: }; michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(ThreadLocalStorage); michael@0: }; michael@0: michael@0: } // namespace base michael@0: michael@0: #endif // BASE_THREADING_THREAD_LOCAL_STORAGE_H_