Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: base/threading/thread_local.h

Issue 1743693002: Revert of Refactor thread_local.h's TLS Implementation to use ThreadLocalStorage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/base.gypi ('k') | base/threading/thread_local_android.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // WARNING: Thread local storage is a bit tricky to get right. Please make sure 5 // WARNING: Thread local storage is a bit tricky to get right. Please make
6 // that this is really the proper solution for what you're trying to achieve. 6 // sure that this is really the proper solution for what you're trying to
7 // Don't prematurely optimize, most likely you can just use a Lock. 7 // achieve. Don't prematurely optimize, most likely you can just use a Lock.
8 // 8 //
9 // These classes implement a wrapper around ThreadLocalStorage::Slot. On 9 // These classes implement a wrapper around the platform's TLS storage
10 // construction, they will allocate a TLS slot, and free the TLS slot on 10 // mechanism. On construction, they will allocate a TLS slot, and free the
11 // destruction. No memory management (creation or destruction) is handled. This 11 // TLS slot on destruction. No memory management (creation or destruction) is
12 // means for uses of ThreadLocalPointer, you must correctly manage the memory 12 // handled. This means for uses of ThreadLocalPointer, you must correctly
13 // yourself, these classes will not destroy the pointer for you. There are no 13 // manage the memory yourself, these classes will not destroy the pointer for
14 // at-thread-exit actions taken by these classes. 14 // you. There are no at-thread-exit actions taken by these classes.
15 // 15 //
16 // ThreadLocalPointer<Type> wraps a Type*. It performs no creation or 16 // ThreadLocalPointer<Type> wraps a Type*. It performs no creation or
17 // destruction, so memory management must be handled elsewhere. The first call 17 // destruction, so memory management must be handled elsewhere. The first call
18 // to Get() on a thread will return NULL. You can update the pointer with a call 18 // to Get() on a thread will return NULL. You can update the pointer with a
19 // to Set(). 19 // call to Set().
20 // 20 //
21 // ThreadLocalBoolean wraps a bool. It will default to false if it has never 21 // ThreadLocalBoolean wraps a bool. It will default to false if it has never
22 // been set otherwise with Set(). 22 // been set otherwise with Set().
23 // 23 //
24 // Thread Safety: An instance of ThreadLocalStorage is completely thread safe 24 // Thread Safety: An instance of ThreadLocalStorage is completely thread safe
25 // once it has been created. If you want to dynamically create an instance, you 25 // once it has been created. If you want to dynamically create an instance,
26 // must of course properly deal with safety and race conditions. This means a 26 // you must of course properly deal with safety and race conditions. This
27 // function-level static initializer is generally inappropiate. 27 // means a function-level static initializer is generally inappropiate.
28 // 28 //
29 // In Android, the system TLS is limited. 29 // In Android, the system TLS is limited, the implementation is backed with
30 // ThreadLocalStorage.
30 // 31 //
31 // Example usage: 32 // Example usage:
32 // // My class is logically attached to a single thread. We cache a pointer 33 // // My class is logically attached to a single thread. We cache a pointer
33 // // on the thread it was created on, so we can implement current(). 34 // // on the thread it was created on, so we can implement current().
34 // MyClass::MyClass() { 35 // MyClass::MyClass() {
35 // DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() == NULL); 36 // DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() == NULL);
36 // Singleton<ThreadLocalPointer<MyClass> >::get()->Set(this); 37 // Singleton<ThreadLocalPointer<MyClass> >::get()->Set(this);
37 // } 38 // }
38 // 39 //
39 // MyClass::~MyClass() { 40 // MyClass::~MyClass() {
40 // DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() != NULL); 41 // DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() != NULL);
41 // Singleton<ThreadLocalPointer<MyClass> >::get()->Set(NULL); 42 // Singleton<ThreadLocalPointer<MyClass> >::get()->Set(NULL);
42 // } 43 // }
43 // 44 //
44 // // Return the current MyClass associated with the calling thread, can be 45 // // Return the current MyClass associated with the calling thread, can be
45 // // NULL if there isn't a MyClass associated. 46 // // NULL if there isn't a MyClass associated.
46 // MyClass* MyClass::current() { 47 // MyClass* MyClass::current() {
47 // return Singleton<ThreadLocalPointer<MyClass> >::get()->Get(); 48 // return Singleton<ThreadLocalPointer<MyClass> >::get()->Get();
48 // } 49 // }
49 50
50 #ifndef BASE_THREADING_THREAD_LOCAL_H_ 51 #ifndef BASE_THREADING_THREAD_LOCAL_H_
51 #define BASE_THREADING_THREAD_LOCAL_H_ 52 #define BASE_THREADING_THREAD_LOCAL_H_
52 53
54 #include "base/base_export.h"
53 #include "base/macros.h" 55 #include "base/macros.h"
54 #include "base/threading/thread_local_storage.h" 56 #include "base/threading/thread_local_storage.h"
57 #include "build/build_config.h"
58
59 #if defined(OS_POSIX)
60 #include <pthread.h>
61 #endif
55 62
56 namespace base { 63 namespace base {
64 namespace internal {
65
66 // Helper functions that abstract the cross-platform APIs. Do not use directly.
67 struct BASE_EXPORT ThreadLocalPlatform {
68 #if defined(OS_WIN)
69 typedef unsigned long SlotType;
70 #elif defined(OS_ANDROID)
71 typedef ThreadLocalStorage::StaticSlot SlotType;
72 #elif defined(OS_POSIX)
73 typedef pthread_key_t SlotType;
74 #endif
75
76 static void AllocateSlot(SlotType* slot);
77 static void FreeSlot(SlotType slot);
78 static void* GetValueFromSlot(SlotType slot);
79 static void SetValueInSlot(SlotType slot, void* value);
80 };
81
82 } // namespace internal
57 83
58 template <typename Type> 84 template <typename Type>
59 class ThreadLocalPointer { 85 class ThreadLocalPointer {
60 public: 86 public:
61 ThreadLocalPointer() = default; 87 ThreadLocalPointer() : slot_() {
62 ~ThreadLocalPointer() = default; 88 internal::ThreadLocalPlatform::AllocateSlot(&slot_);
89 }
90
91 ~ThreadLocalPointer() {
92 internal::ThreadLocalPlatform::FreeSlot(slot_);
93 }
63 94
64 Type* Get() { 95 Type* Get() {
65 return static_cast<Type*>(slot_.Get()); 96 return static_cast<Type*>(
97 internal::ThreadLocalPlatform::GetValueFromSlot(slot_));
66 } 98 }
67 99
68 void Set(Type* ptr) { 100 void Set(Type* ptr) {
69 slot_.Set(const_cast<void*>(static_cast<const void*>(ptr))); 101 internal::ThreadLocalPlatform::SetValueInSlot(
102 slot_, const_cast<void*>(static_cast<const void*>(ptr)));
70 } 103 }
71 104
72 private: 105 private:
73 ThreadLocalStorage::Slot slot_; 106 typedef internal::ThreadLocalPlatform::SlotType SlotType;
107
108 SlotType slot_;
74 109
75 DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>); 110 DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>);
76 }; 111 };
77 112
78 class ThreadLocalBoolean { 113 class ThreadLocalBoolean {
79 public: 114 public:
80 ThreadLocalBoolean() = default; 115 ThreadLocalBoolean() {}
81 ~ThreadLocalBoolean() = default; 116 ~ThreadLocalBoolean() {}
82 117
83 bool Get() { 118 bool Get() {
84 return tlp_.Get() != nullptr; 119 return tlp_.Get() != NULL;
85 } 120 }
86 121
87 void Set(bool val) { 122 void Set(bool val) {
88 tlp_.Set(val ? this : nullptr); 123 tlp_.Set(val ? this : NULL);
89 } 124 }
90 125
91 private: 126 private:
92 ThreadLocalPointer<void> tlp_; 127 ThreadLocalPointer<void> tlp_;
93 128
94 DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean); 129 DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean);
95 }; 130 };
96 131
97 } // namespace base 132 } // namespace base
98 133
99 #endif // BASE_THREADING_THREAD_LOCAL_H_ 134 #endif // BASE_THREADING_THREAD_LOCAL_H_
OLDNEW
« no previous file with comments | « base/base.gypi ('k') | base/threading/thread_local_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698