| OLD | NEW |
| 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 30 matching lines...) Expand all Loading... |
| 41 | 41 |
| 42 #ifndef WTF_ThreadSpecific_h | 42 #ifndef WTF_ThreadSpecific_h |
| 43 #define WTF_ThreadSpecific_h | 43 #define WTF_ThreadSpecific_h |
| 44 | 44 |
| 45 #include "wtf/Noncopyable.h" | 45 #include "wtf/Noncopyable.h" |
| 46 #include "wtf/StdLibExtras.h" | 46 #include "wtf/StdLibExtras.h" |
| 47 #include "wtf/WTFExport.h" | 47 #include "wtf/WTFExport.h" |
| 48 | 48 |
| 49 #if USE(PTHREADS) | 49 #if USE(PTHREADS) |
| 50 #include <pthread.h> | 50 #include <pthread.h> |
| 51 #elif OS(WINDOWS) | 51 #elif OS(WIN) |
| 52 #include <windows.h> | 52 #include <windows.h> |
| 53 #endif | 53 #endif |
| 54 | 54 |
| 55 namespace WTF { | 55 namespace WTF { |
| 56 | 56 |
| 57 #if OS(WINDOWS) | 57 #if OS(WIN) |
| 58 // ThreadSpecificThreadExit should be called each time when a thread is detached
. | 58 // ThreadSpecificThreadExit should be called each time when a thread is detached
. |
| 59 // This is done automatically for threads created with WTF::createThread. | 59 // This is done automatically for threads created with WTF::createThread. |
| 60 WTF_EXPORT void ThreadSpecificThreadExit(); | 60 WTF_EXPORT void ThreadSpecificThreadExit(); |
| 61 #endif | 61 #endif |
| 62 | 62 |
| 63 template<typename T> class ThreadSpecific { | 63 template<typename T> class ThreadSpecific { |
| 64 WTF_MAKE_NONCOPYABLE(ThreadSpecific); | 64 WTF_MAKE_NONCOPYABLE(ThreadSpecific); |
| 65 public: | 65 public: |
| 66 ThreadSpecific(); | 66 ThreadSpecific(); |
| 67 bool isSet(); // Useful as a fast check to see if this thread has set this v
alue. | 67 bool isSet(); // Useful as a fast check to see if this thread has set this v
alue. |
| 68 T* operator->(); | 68 T* operator->(); |
| 69 operator T*(); | 69 operator T*(); |
| 70 T& operator*(); | 70 T& operator*(); |
| 71 | 71 |
| 72 private: | 72 private: |
| 73 #if OS(WINDOWS) | 73 #if OS(WIN) |
| 74 WTF_EXPORT friend void ThreadSpecificThreadExit(); | 74 WTF_EXPORT friend void ThreadSpecificThreadExit(); |
| 75 #endif | 75 #endif |
| 76 | 76 |
| 77 // Not implemented. It's technically possible to destroy a thread specific k
ey, but one would need | 77 // Not implemented. It's technically possible to destroy a thread specific k
ey, but one would need |
| 78 // to make sure that all values have been destroyed already (usually, that a
ll threads that used it | 78 // to make sure that all values have been destroyed already (usually, that a
ll threads that used it |
| 79 // have exited). It's unlikely that any user of this call will be in that si
tuation - and having | 79 // have exited). It's unlikely that any user of this call will be in that si
tuation - and having |
| 80 // a destructor defined can be confusing, given that it has such strong pre-
requisites to work correctly. | 80 // a destructor defined can be confusing, given that it has such strong pre-
requisites to work correctly. |
| 81 ~ThreadSpecific(); | 81 ~ThreadSpecific(); |
| 82 | 82 |
| 83 T* get(); | 83 T* get(); |
| 84 void set(T*); | 84 void set(T*); |
| 85 void static destroy(void* ptr); | 85 void static destroy(void* ptr); |
| 86 | 86 |
| 87 struct Data { | 87 struct Data { |
| 88 WTF_MAKE_NONCOPYABLE(Data); | 88 WTF_MAKE_NONCOPYABLE(Data); |
| 89 public: | 89 public: |
| 90 Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {} | 90 Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {} |
| 91 | 91 |
| 92 T* value; | 92 T* value; |
| 93 ThreadSpecific<T>* owner; | 93 ThreadSpecific<T>* owner; |
| 94 #if OS(WINDOWS) | 94 #if OS(WIN) |
| 95 void (*destructor)(void*); | 95 void (*destructor)(void*); |
| 96 #endif | 96 #endif |
| 97 }; | 97 }; |
| 98 | 98 |
| 99 #if USE(PTHREADS) | 99 #if USE(PTHREADS) |
| 100 pthread_key_t m_key; | 100 pthread_key_t m_key; |
| 101 #elif OS(WINDOWS) | 101 #elif OS(WIN) |
| 102 int m_index; | 102 int m_index; |
| 103 #endif | 103 #endif |
| 104 }; | 104 }; |
| 105 | 105 |
| 106 #if USE(PTHREADS) | 106 #if USE(PTHREADS) |
| 107 | 107 |
| 108 typedef pthread_key_t ThreadSpecificKey; | 108 typedef pthread_key_t ThreadSpecificKey; |
| 109 | 109 |
| 110 inline void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(v
oid *)) | 110 inline void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(v
oid *)) |
| 111 { | 111 { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 return data ? data->value : 0; | 146 return data ? data->value : 0; |
| 147 } | 147 } |
| 148 | 148 |
| 149 template<typename T> | 149 template<typename T> |
| 150 inline void ThreadSpecific<T>::set(T* ptr) | 150 inline void ThreadSpecific<T>::set(T* ptr) |
| 151 { | 151 { |
| 152 ASSERT(!get()); | 152 ASSERT(!get()); |
| 153 pthread_setspecific(m_key, new Data(ptr, this)); | 153 pthread_setspecific(m_key, new Data(ptr, this)); |
| 154 } | 154 } |
| 155 | 155 |
| 156 #elif OS(WINDOWS) | 156 #elif OS(WIN) |
| 157 | 157 |
| 158 // TLS_OUT_OF_INDEXES is not defined on WinCE. | 158 // TLS_OUT_OF_INDEXES is not defined on WinCE. |
| 159 #ifndef TLS_OUT_OF_INDEXES | 159 #ifndef TLS_OUT_OF_INDEXES |
| 160 #define TLS_OUT_OF_INDEXES 0xffffffff | 160 #define TLS_OUT_OF_INDEXES 0xffffffff |
| 161 #endif | 161 #endif |
| 162 | 162 |
| 163 // The maximum number of TLS keys that can be created. For simplification, we as
sume that: | 163 // The maximum number of TLS keys that can be created. For simplification, we as
sume that: |
| 164 // 1) Once the instance of ThreadSpecific<> is created, it will not be destructe
d until the program dies. | 164 // 1) Once the instance of ThreadSpecific<> is created, it will not be destructe
d until the program dies. |
| 165 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed
number should be far enough. | 165 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed
number should be far enough. |
| 166 const int kMaxTlsKeySize = 256; | 166 const int kMaxTlsKeySize = 256; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 // We want get() to keep working while data destructor works, because it can
be called indirectly by the destructor. | 226 // We want get() to keep working while data destructor works, because it can
be called indirectly by the destructor. |
| 227 // Some pthreads implementations zero out the pointer before calling destroy
(), so we temporarily reset it. | 227 // Some pthreads implementations zero out the pointer before calling destroy
(), so we temporarily reset it. |
| 228 pthread_setspecific(data->owner->m_key, ptr); | 228 pthread_setspecific(data->owner->m_key, ptr); |
| 229 #endif | 229 #endif |
| 230 | 230 |
| 231 data->value->~T(); | 231 data->value->~T(); |
| 232 fastFree(data->value); | 232 fastFree(data->value); |
| 233 | 233 |
| 234 #if USE(PTHREADS) | 234 #if USE(PTHREADS) |
| 235 pthread_setspecific(data->owner->m_key, 0); | 235 pthread_setspecific(data->owner->m_key, 0); |
| 236 #elif OS(WINDOWS) | 236 #elif OS(WIN) |
| 237 TlsSetValue(tlsKeys()[data->owner->m_index], 0); | 237 TlsSetValue(tlsKeys()[data->owner->m_index], 0); |
| 238 #else | 238 #else |
| 239 #error ThreadSpecific is not implemented for this platform. | 239 #error ThreadSpecific is not implemented for this platform. |
| 240 #endif | 240 #endif |
| 241 | 241 |
| 242 delete data; | 242 delete data; |
| 243 } | 243 } |
| 244 | 244 |
| 245 template<typename T> | 245 template<typename T> |
| 246 inline bool ThreadSpecific<T>::isSet() | 246 inline bool ThreadSpecific<T>::isSet() |
| (...skipping 23 matching lines...) Expand all Loading... |
| 270 | 270 |
| 271 template<typename T> | 271 template<typename T> |
| 272 inline T& ThreadSpecific<T>::operator*() | 272 inline T& ThreadSpecific<T>::operator*() |
| 273 { | 273 { |
| 274 return *operator T*(); | 274 return *operator T*(); |
| 275 } | 275 } |
| 276 | 276 |
| 277 } // namespace WTF | 277 } // namespace WTF |
| 278 | 278 |
| 279 #endif // WTF_ThreadSpecific_h | 279 #endif // WTF_ThreadSpecific_h |
| OLD | NEW |