1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/threading/thread_local.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,128 @@ 1.4 +// Copyright (c) 2011 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 wrapper 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_THREADING_THREAD_LOCAL_H_ 1.52 +#define BASE_THREADING_THREAD_LOCAL_H_ 1.53 + 1.54 +#include "base/base_export.h" 1.55 +#include "base/basictypes.h" 1.56 + 1.57 +#if defined(OS_POSIX) 1.58 +#include <pthread.h> 1.59 +#endif 1.60 + 1.61 +namespace base { 1.62 + 1.63 +namespace internal { 1.64 + 1.65 +// Helper functions that abstract the cross-platform APIs. Do not use directly. 1.66 +struct BASE_EXPORT ThreadLocalPlatform { 1.67 +#if defined(OS_WIN) 1.68 + typedef unsigned long SlotType; 1.69 +#elif defined(OS_POSIX) 1.70 + typedef pthread_key_t SlotType; 1.71 +#endif 1.72 + 1.73 + static void AllocateSlot(SlotType& slot); 1.74 + static void FreeSlot(SlotType& slot); 1.75 + static void* GetValueFromSlot(SlotType& slot); 1.76 + static void SetValueInSlot(SlotType& slot, void* value); 1.77 +}; 1.78 + 1.79 +} // namespace internal 1.80 + 1.81 +template <typename Type> 1.82 +class ThreadLocalPointer { 1.83 + public: 1.84 + ThreadLocalPointer() : slot_() { 1.85 + internal::ThreadLocalPlatform::AllocateSlot(slot_); 1.86 + } 1.87 + 1.88 + ~ThreadLocalPointer() { 1.89 + internal::ThreadLocalPlatform::FreeSlot(slot_); 1.90 + } 1.91 + 1.92 + Type* Get() { 1.93 + return static_cast<Type*>( 1.94 + internal::ThreadLocalPlatform::GetValueFromSlot(slot_)); 1.95 + } 1.96 + 1.97 + void Set(Type* ptr) { 1.98 + internal::ThreadLocalPlatform::SetValueInSlot( 1.99 + slot_, const_cast<void*>(static_cast<const void*>(ptr))); 1.100 + } 1.101 + 1.102 + private: 1.103 + typedef internal::ThreadLocalPlatform::SlotType SlotType; 1.104 + 1.105 + SlotType slot_; 1.106 + 1.107 + DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>); 1.108 +}; 1.109 + 1.110 +class ThreadLocalBoolean { 1.111 + public: 1.112 + ThreadLocalBoolean() { } 1.113 + ~ThreadLocalBoolean() { } 1.114 + 1.115 + bool Get() { 1.116 + return tlp_.Get() != NULL; 1.117 + } 1.118 + 1.119 + void Set(bool val) { 1.120 + tlp_.Set(val ? this : NULL); 1.121 + } 1.122 + 1.123 + private: 1.124 + ThreadLocalPointer<void> tlp_; 1.125 + 1.126 + DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean); 1.127 +}; 1.128 + 1.129 +} // namespace base 1.130 + 1.131 +#endif // BASE_THREADING_THREAD_LOCAL_H_