1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/thread_local.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,121 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +// WARNING: Thread local storage is a bit tricky to get right. Please make 1.9 +// sure that this is really the proper solution for what you're trying to 1.10 +// achieve. Don't prematurely optimize, most likely you can just use a Lock. 1.11 +// 1.12 +// These classes implement a warpper around the platform's TLS storage 1.13 +// mechanism. On construction, they will allocate a TLS slot, and free the 1.14 +// TLS slot on destruction. No memory management (creation or destruction) is 1.15 +// handled. This means for uses of ThreadLocalPointer, you must correctly 1.16 +// manage the memory yourself, these classes will not destroy the pointer for 1.17 +// you. There are no at-thread-exit actions taken by these classes. 1.18 +// 1.19 +// ThreadLocalPointer<Type> wraps a Type*. It performs no creation or 1.20 +// destruction, so memory management must be handled elsewhere. The first call 1.21 +// to Get() on a thread will return NULL. You can update the pointer with a 1.22 +// call to Set(). 1.23 +// 1.24 +// ThreadLocalBoolean wraps a bool. It will default to false if it has never 1.25 +// been set otherwise with Set(). 1.26 +// 1.27 +// Thread Safety: An instance of ThreadLocalStorage is completely thread safe 1.28 +// once it has been created. If you want to dynamically create an instance, 1.29 +// you must of course properly deal with safety and race conditions. This 1.30 +// means a function-level static initializer is generally inappropiate. 1.31 +// 1.32 +// Example usage: 1.33 +// // My class is logically attached to a single thread. We cache a pointer 1.34 +// // on the thread it was created on, so we can implement current(). 1.35 +// MyClass::MyClass() { 1.36 +// DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() == NULL); 1.37 +// Singleton<ThreadLocalPointer<MyClass> >::get()->Set(this); 1.38 +// } 1.39 +// 1.40 +// MyClass::~MyClass() { 1.41 +// DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() != NULL); 1.42 +// Singleton<ThreadLocalPointer<MyClass> >::get()->Set(NULL); 1.43 +// } 1.44 +// 1.45 +// // Return the current MyClass associated with the calling thread, can be 1.46 +// // NULL if there isn't a MyClass associated. 1.47 +// MyClass* MyClass::current() { 1.48 +// return Singleton<ThreadLocalPointer<MyClass> >::get()->Get(); 1.49 +// } 1.50 + 1.51 +#ifndef BASE_THREAD_LOCAL_H_ 1.52 +#define BASE_THREAD_LOCAL_H_ 1.53 + 1.54 +#include "base/basictypes.h" 1.55 + 1.56 +#if defined(OS_POSIX) 1.57 +#include <pthread.h> 1.58 +#endif 1.59 + 1.60 +namespace base { 1.61 + 1.62 +// Helper functions that abstract the cross-platform APIs. Do not use directly. 1.63 +struct ThreadLocalPlatform { 1.64 +#if defined(OS_WIN) 1.65 + typedef int SlotType; 1.66 +#elif defined(OS_POSIX) 1.67 + typedef pthread_key_t SlotType; 1.68 +#endif 1.69 + 1.70 + static void AllocateSlot(SlotType& slot); 1.71 + static void FreeSlot(SlotType& slot); 1.72 + static void* GetValueFromSlot(SlotType& slot); 1.73 + static void SetValueInSlot(SlotType& slot, void* value); 1.74 +}; 1.75 + 1.76 +template <typename Type> 1.77 +class ThreadLocalPointer { 1.78 + public: 1.79 + ThreadLocalPointer() : slot_() { 1.80 + ThreadLocalPlatform::AllocateSlot(slot_); 1.81 + } 1.82 + 1.83 + ~ThreadLocalPointer() { 1.84 + ThreadLocalPlatform::FreeSlot(slot_); 1.85 + } 1.86 + 1.87 + Type* Get() { 1.88 + return static_cast<Type*>(ThreadLocalPlatform::GetValueFromSlot(slot_)); 1.89 + } 1.90 + 1.91 + void Set(Type* ptr) { 1.92 + ThreadLocalPlatform::SetValueInSlot(slot_, ptr); 1.93 + } 1.94 + 1.95 + private: 1.96 + typedef ThreadLocalPlatform::SlotType SlotType; 1.97 + 1.98 + SlotType slot_; 1.99 + 1.100 + DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>); 1.101 +}; 1.102 + 1.103 +class ThreadLocalBoolean { 1.104 + public: 1.105 + ThreadLocalBoolean() { } 1.106 + ~ThreadLocalBoolean() { } 1.107 + 1.108 + bool Get() { 1.109 + return tlp_.Get() != NULL; 1.110 + } 1.111 + 1.112 + void Set(bool val) { 1.113 + tlp_.Set(reinterpret_cast<void*>(val ? 1 : 0)); 1.114 + } 1.115 + 1.116 + private: 1.117 + ThreadLocalPointer<void> tlp_; 1.118 + 1.119 + DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean); 1.120 +}; 1.121 + 1.122 +} // namespace base 1.123 + 1.124 +#endif // BASE_THREAD_LOCAL_H_