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

Side by Side Diff: third_party/WebKit/Source/wtf/ThreadSpecific.h

Issue 2386843002: reflow comments in wtf (Closed)
Patch Set: comments (heh!) Created 4 years, 2 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Jian Li <jianli@chromium.org> 3 * Copyright (C) 2009 Jian Li <jianli@chromium.org>
4 * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com> 4 * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com>
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 9 *
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 #if OS(POSIX) 52 #if OS(POSIX)
53 #include <pthread.h> 53 #include <pthread.h>
54 #elif OS(WIN) 54 #elif OS(WIN)
55 #include <windows.h> 55 #include <windows.h>
56 #endif 56 #endif
57 57
58 namespace WTF { 58 namespace WTF {
59 59
60 #if OS(WIN) 60 #if OS(WIN)
61 // ThreadSpecificThreadExit should be called each time when a thread is detached . 61 // ThreadSpecificThreadExit should be called each time when a thread is
62 // detached.
62 // This is done automatically for threads created with WTF::createThread. 63 // This is done automatically for threads created with WTF::createThread.
63 WTF_EXPORT void ThreadSpecificThreadExit(); 64 WTF_EXPORT void ThreadSpecificThreadExit();
64 #endif 65 #endif
65 66
66 template <typename T> 67 template <typename T>
67 class ThreadSpecific { 68 class ThreadSpecific {
68 USING_FAST_MALLOC(ThreadSpecific); 69 USING_FAST_MALLOC(ThreadSpecific);
69 WTF_MAKE_NONCOPYABLE(ThreadSpecific); 70 WTF_MAKE_NONCOPYABLE(ThreadSpecific);
70 71
71 public: 72 public:
72 ThreadSpecific(); 73 ThreadSpecific();
73 bool 74 bool
74 isSet(); // Useful as a fast check to see if this thread has set this value. 75 isSet(); // Useful as a fast check to see if this thread has set this value.
75 T* operator->(); 76 T* operator->();
76 operator T*(); 77 operator T*();
77 T& operator*(); 78 T& operator*();
78 79
79 private: 80 private:
80 #if OS(WIN) 81 #if OS(WIN)
81 WTF_EXPORT friend void ThreadSpecificThreadExit(); 82 WTF_EXPORT friend void ThreadSpecificThreadExit();
82 #endif 83 #endif
83 84
84 // Not implemented. It's technically possible to destroy a thread specific key , but one would need 85 // Not implemented. It's technically possible to destroy a thread specific
85 // to make sure that all values have been destroyed already (usually, that all threads that used it 86 // key, but one would need to make sure that all values have been destroyed
86 // have exited). It's unlikely that any user of this call will be in that situ ation - and having 87 // already (usually, that all threads that used it have exited). It's
87 // a destructor defined can be confusing, given that it has such strong pre-re quisites to work correctly. 88 // unlikely that any user of this call will be in that situation - and having
89 // a destructor defined can be confusing, given that it has such strong
90 // pre-requisites to work correctly.
88 ~ThreadSpecific(); 91 ~ThreadSpecific();
89 92
90 T* get(); 93 T* get();
91 void set(T*); 94 void set(T*);
92 void static destroy(void* ptr); 95 void static destroy(void* ptr);
93 96
94 struct Data { 97 struct Data {
95 WTF_MAKE_NONCOPYABLE(Data); 98 WTF_MAKE_NONCOPYABLE(Data);
96 99
97 public: 100 public:
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 pthread_setspecific(m_key, new Data(ptr, this)); 158 pthread_setspecific(m_key, new Data(ptr, this));
156 } 159 }
157 160
158 #elif OS(WIN) 161 #elif OS(WIN)
159 162
160 // TLS_OUT_OF_INDEXES is not defined on WinCE. 163 // TLS_OUT_OF_INDEXES is not defined on WinCE.
161 #ifndef TLS_OUT_OF_INDEXES 164 #ifndef TLS_OUT_OF_INDEXES
162 #define TLS_OUT_OF_INDEXES 0xffffffff 165 #define TLS_OUT_OF_INDEXES 0xffffffff
163 #endif 166 #endif
164 167
165 // The maximum number of TLS keys that can be created. For simplification, we as sume that: 168 // The maximum number of TLS keys that can be created. For simplification, we
166 // 1) Once the instance of ThreadSpecific<> is created, it will not be destructe d until the program dies. 169 // assume that:
167 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough. 170 // 1) Once the instance of ThreadSpecific<> is created, it will not be
171 // destructed until the program dies.
172 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed
173 // number should be far enough.
168 const int kMaxTlsKeySize = 256; 174 const int kMaxTlsKeySize = 256;
169 175
170 WTF_EXPORT long& tlsKeyCount(); 176 WTF_EXPORT long& tlsKeyCount();
171 WTF_EXPORT DWORD* tlsKeys(); 177 WTF_EXPORT DWORD* tlsKeys();
172 178
173 class PlatformThreadSpecificKey; 179 class PlatformThreadSpecificKey;
174 typedef PlatformThreadSpecificKey* ThreadSpecificKey; 180 typedef PlatformThreadSpecificKey* ThreadSpecificKey;
175 181
176 WTF_EXPORT void threadSpecificKeyCreate(ThreadSpecificKey*, void (*)(void*)); 182 WTF_EXPORT void threadSpecificKeyCreate(ThreadSpecificKey*, void (*)(void*));
177 WTF_EXPORT void threadSpecificKeyDelete(ThreadSpecificKey); 183 WTF_EXPORT void threadSpecificKeyDelete(ThreadSpecificKey);
178 WTF_EXPORT void threadSpecificSet(ThreadSpecificKey, void*); 184 WTF_EXPORT void threadSpecificSet(ThreadSpecificKey, void*);
179 WTF_EXPORT void* threadSpecificGet(ThreadSpecificKey); 185 WTF_EXPORT void* threadSpecificGet(ThreadSpecificKey);
180 186
181 template <typename T> 187 template <typename T>
182 inline ThreadSpecific<T>::ThreadSpecific() : m_index(-1) { 188 inline ThreadSpecific<T>::ThreadSpecific() : m_index(-1) {
183 DWORD tlsKey = TlsAlloc(); 189 DWORD tlsKey = TlsAlloc();
184 if (tlsKey == TLS_OUT_OF_INDEXES) 190 if (tlsKey == TLS_OUT_OF_INDEXES)
185 CRASH(); 191 CRASH();
186 192
187 m_index = InterlockedIncrement(&tlsKeyCount()) - 1; 193 m_index = InterlockedIncrement(&tlsKeyCount()) - 1;
188 if (m_index >= kMaxTlsKeySize) 194 if (m_index >= kMaxTlsKeySize)
189 CRASH(); 195 CRASH();
190 tlsKeys()[m_index] = tlsKey; 196 tlsKeys()[m_index] = tlsKey;
191 } 197 }
192 198
193 template <typename T> 199 template <typename T>
194 inline ThreadSpecific<T>::~ThreadSpecific() { 200 inline ThreadSpecific<T>::~ThreadSpecific() {
195 // Does not invoke destructor functions. They will be called from ThreadSpecif icThreadExit when the thread is detached. 201 // Does not invoke destructor functions. They will be called from
202 // ThreadSpecificThreadExit when the thread is detached.
196 TlsFree(tlsKeys()[m_index]); 203 TlsFree(tlsKeys()[m_index]);
197 } 204 }
198 205
199 template <typename T> 206 template <typename T>
200 inline T* ThreadSpecific<T>::get() { 207 inline T* ThreadSpecific<T>::get() {
201 Data* data = static_cast<Data*>(TlsGetValue(tlsKeys()[m_index])); 208 Data* data = static_cast<Data*>(TlsGetValue(tlsKeys()[m_index]));
202 return data ? data->value : 0; 209 return data ? data->value : 0;
203 } 210 }
204 211
205 template <typename T> 212 template <typename T>
206 inline void ThreadSpecific<T>::set(T* ptr) { 213 inline void ThreadSpecific<T>::set(T* ptr) {
207 ASSERT(!get()); 214 ASSERT(!get());
208 Data* data = new Data(ptr, this); 215 Data* data = new Data(ptr, this);
209 data->destructor = &ThreadSpecific<T>::destroy; 216 data->destructor = &ThreadSpecific<T>::destroy;
210 TlsSetValue(tlsKeys()[m_index], data); 217 TlsSetValue(tlsKeys()[m_index], data);
211 } 218 }
212 219
213 #else 220 #else
214 #error ThreadSpecific is not implemented for this platform. 221 #error ThreadSpecific is not implemented for this platform.
215 #endif 222 #endif
216 223
217 template <typename T> 224 template <typename T>
218 inline void ThreadSpecific<T>::destroy(void* ptr) { 225 inline void ThreadSpecific<T>::destroy(void* ptr) {
219 if (isShutdown()) 226 if (isShutdown())
220 return; 227 return;
221 228
222 Data* data = static_cast<Data*>(ptr); 229 Data* data = static_cast<Data*>(ptr);
223 230
224 #if OS(POSIX) 231 #if OS(POSIX)
225 // We want get() to keep working while data destructor works, because it can b e called indirectly by the destructor. 232 // We want get() to keep working while data destructor works, because it can
226 // Some pthreads implementations zero out the pointer before calling destroy() , so we temporarily reset it. 233 // be called indirectly by the destructor. Some pthreads implementations
234 // zero out the pointer before calling destroy(), so we temporarily reset it.
227 pthread_setspecific(data->owner->m_key, ptr); 235 pthread_setspecific(data->owner->m_key, ptr);
228 #endif 236 #endif
229 237
230 data->value->~T(); 238 data->value->~T();
231 Partitions::fastFree(data->value); 239 Partitions::fastFree(data->value);
232 240
233 #if OS(POSIX) 241 #if OS(POSIX)
234 pthread_setspecific(data->owner->m_key, 0); 242 pthread_setspecific(data->owner->m_key, 0);
235 #elif OS(WIN) 243 #elif OS(WIN)
236 TlsSetValue(tlsKeys()[data->owner->m_index], 0); 244 TlsSetValue(tlsKeys()[data->owner->m_index], 0);
237 #else 245 #else
238 #error ThreadSpecific is not implemented for this platform. 246 #error ThreadSpecific is not implemented for this platform.
239 #endif 247 #endif
240 248
241 delete data; 249 delete data;
242 } 250 }
243 251
244 template <typename T> 252 template <typename T>
245 inline bool ThreadSpecific<T>::isSet() { 253 inline bool ThreadSpecific<T>::isSet() {
246 return !!get(); 254 return !!get();
247 } 255 }
248 256
249 template <typename T> 257 template <typename T>
250 inline ThreadSpecific<T>::operator T*() { 258 inline ThreadSpecific<T>::operator T*() {
251 T* ptr = static_cast<T*>(get()); 259 T* ptr = static_cast<T*>(get());
252 if (!ptr) { 260 if (!ptr) {
253 // Set up thread-specific value's memory pointer before invoking constructor , in case any function it calls 261 // Set up thread-specific value's memory pointer before invoking
262 // constructor, in case any function it calls
254 // needs to access the value, to avoid recursion. 263 // needs to access the value, to avoid recursion.
255 ptr = static_cast<T*>(Partitions::fastZeroedMalloc( 264 ptr = static_cast<T*>(Partitions::fastZeroedMalloc(
256 sizeof(T), WTF_HEAP_PROFILER_TYPE_NAME(T))); 265 sizeof(T), WTF_HEAP_PROFILER_TYPE_NAME(T)));
257 set(ptr); 266 set(ptr);
258 new (NotNull, ptr) T; 267 new (NotNull, ptr) T;
259 } 268 }
260 return ptr; 269 return ptr;
261 } 270 }
262 271
263 template <typename T> 272 template <typename T>
264 inline T* ThreadSpecific<T>::operator->() { 273 inline T* ThreadSpecific<T>::operator->() {
265 return operator T*(); 274 return operator T*();
266 } 275 }
267 276
268 template <typename T> 277 template <typename T>
269 inline T& ThreadSpecific<T>::operator*() { 278 inline T& ThreadSpecific<T>::operator*() {
270 return *operator T*(); 279 return *operator T*();
271 } 280 }
272 281
273 } // namespace WTF 282 } // namespace WTF
274 283
275 using WTF::ThreadSpecific; 284 using WTF::ThreadSpecific;
276 285
277 #endif // WTF_ThreadSpecific_h 286 #endif // WTF_ThreadSpecific_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/ThreadRestrictionVerifier.h ('k') | third_party/WebKit/Source/wtf/ThreadSpecificWin.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698