| 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 24 matching lines...) Expand all Loading... |
| 35 * repeatedly if there is still non-NULL value associated with the function. | 35 * repeatedly if there is still non-NULL value associated with the function. |
| 36 * @ In Windows native implementation, the destructor function will be called | 36 * @ In Windows native implementation, the destructor function will be called |
| 37 * only once. | 37 * only once. |
| 38 * This semantic discrepancy does not impose any problem because nowhere in | 38 * This semantic discrepancy does not impose any problem because nowhere in |
| 39 * WebKit the repeated call bahavior is utilized. | 39 * WebKit the repeated call bahavior is utilized. |
| 40 */ | 40 */ |
| 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/AddressSanitizer.h" | |
| 46 #include "wtf/Allocator.h" | 45 #include "wtf/Allocator.h" |
| 47 #include "wtf/Noncopyable.h" | 46 #include "wtf/Noncopyable.h" |
| 48 #include "wtf/StdLibExtras.h" | 47 #include "wtf/StdLibExtras.h" |
| 49 #include "wtf/WTF.h" | 48 #include "wtf/WTF.h" |
| 50 #include "wtf/WTFExport.h" | 49 #include "wtf/WTFExport.h" |
| 51 #include "wtf/allocator/Partitions.h" | 50 #include "wtf/allocator/Partitions.h" |
| 52 | 51 |
| 53 #if OS(POSIX) | 52 #if OS(POSIX) |
| 54 #include <pthread.h> | 53 #include <pthread.h> |
| 55 #elif OS(WIN) | 54 #elif OS(WIN) |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 { | 148 { |
| 150 Data* data = static_cast<Data*>(pthread_getspecific(m_key)); | 149 Data* data = static_cast<Data*>(pthread_getspecific(m_key)); |
| 151 return data ? data->value : 0; | 150 return data ? data->value : 0; |
| 152 } | 151 } |
| 153 | 152 |
| 154 template<typename T> | 153 template<typename T> |
| 155 inline void ThreadSpecific<T>::set(T* ptr) | 154 inline void ThreadSpecific<T>::set(T* ptr) |
| 156 { | 155 { |
| 157 ASSERT(!get()); | 156 ASSERT(!get()); |
| 158 pthread_setspecific(m_key, new Data(ptr, this)); | 157 pthread_setspecific(m_key, new Data(ptr, this)); |
| 159 __lsan_register_root_region(ptr, sizeof(Data)); | |
| 160 } | 158 } |
| 161 | 159 |
| 162 #elif OS(WIN) | 160 #elif OS(WIN) |
| 163 | 161 |
| 164 // TLS_OUT_OF_INDEXES is not defined on WinCE. | 162 // TLS_OUT_OF_INDEXES is not defined on WinCE. |
| 165 #ifndef TLS_OUT_OF_INDEXES | 163 #ifndef TLS_OUT_OF_INDEXES |
| 166 #define TLS_OUT_OF_INDEXES 0xffffffff | 164 #define TLS_OUT_OF_INDEXES 0xffffffff |
| 167 #endif | 165 #endif |
| 168 | 166 |
| 169 // The maximum number of TLS keys that can be created. For simplification, we as
sume that: | 167 // The maximum number of TLS keys that can be created. For simplification, we as
sume that: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 { | 206 { |
| 209 Data* data = static_cast<Data*>(TlsGetValue(tlsKeys()[m_index])); | 207 Data* data = static_cast<Data*>(TlsGetValue(tlsKeys()[m_index])); |
| 210 return data ? data->value : 0; | 208 return data ? data->value : 0; |
| 211 } | 209 } |
| 212 | 210 |
| 213 template<typename T> | 211 template<typename T> |
| 214 inline void ThreadSpecific<T>::set(T* ptr) | 212 inline void ThreadSpecific<T>::set(T* ptr) |
| 215 { | 213 { |
| 216 ASSERT(!get()); | 214 ASSERT(!get()); |
| 217 Data* data = new Data(ptr, this); | 215 Data* data = new Data(ptr, this); |
| 218 __lsan_register_root_region(ptr, sizeof(Data)); | |
| 219 data->destructor = &ThreadSpecific<T>::destroy; | 216 data->destructor = &ThreadSpecific<T>::destroy; |
| 220 TlsSetValue(tlsKeys()[m_index], data); | 217 TlsSetValue(tlsKeys()[m_index], data); |
| 221 } | 218 } |
| 222 | 219 |
| 223 #else | 220 #else |
| 224 #error ThreadSpecific is not implemented for this platform. | 221 #error ThreadSpecific is not implemented for this platform. |
| 225 #endif | 222 #endif |
| 226 | 223 |
| 227 template<typename T> | 224 template<typename T> |
| 228 inline void ThreadSpecific<T>::destroy(void* ptr) | 225 inline void ThreadSpecific<T>::destroy(void* ptr) |
| 229 { | 226 { |
| 230 // Never call destructors on the main thread. | 227 if (isShutdown()) |
| 231 // This is fine because Blink no longer has a graceful shutdown sequence. | |
| 232 if (isMainThread()) | |
| 233 return; | 228 return; |
| 234 | 229 |
| 235 Data* data = static_cast<Data*>(ptr); | 230 Data* data = static_cast<Data*>(ptr); |
| 236 | 231 |
| 237 #if OS(POSIX) | 232 #if OS(POSIX) |
| 238 // We want get() to keep working while data destructor works, because it can
be called indirectly by the destructor. | 233 // We want get() to keep working while data destructor works, because it can
be called indirectly by the destructor. |
| 239 // Some pthreads implementations zero out the pointer before calling destroy
(), so we temporarily reset it. | 234 // Some pthreads implementations zero out the pointer before calling destroy
(), so we temporarily reset it. |
| 240 pthread_setspecific(data->owner->m_key, ptr); | 235 pthread_setspecific(data->owner->m_key, ptr); |
| 241 #endif | 236 #endif |
| 242 | 237 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 263 template<typename T> | 258 template<typename T> |
| 264 inline ThreadSpecific<T>::operator T*() | 259 inline ThreadSpecific<T>::operator T*() |
| 265 { | 260 { |
| 266 T* ptr = static_cast<T*>(get()); | 261 T* ptr = static_cast<T*>(get()); |
| 267 if (!ptr) { | 262 if (!ptr) { |
| 268 // Set up thread-specific value's memory pointer before invoking constru
ctor, in case any function it calls | 263 // Set up thread-specific value's memory pointer before invoking constru
ctor, in case any function it calls |
| 269 // needs to access the value, to avoid recursion. | 264 // needs to access the value, to avoid recursion. |
| 270 ptr = static_cast<T*>(Partitions::fastZeroedMalloc(sizeof(T), WTF_HEAP_P
ROFILER_TYPE_NAME(T))); | 265 ptr = static_cast<T*>(Partitions::fastZeroedMalloc(sizeof(T), WTF_HEAP_P
ROFILER_TYPE_NAME(T))); |
| 271 set(ptr); | 266 set(ptr); |
| 272 new (NotNull, ptr) T; | 267 new (NotNull, ptr) T; |
| 273 __lsan_register_root_region(ptr, sizeof(T)); | |
| 274 } | 268 } |
| 275 return ptr; | 269 return ptr; |
| 276 } | 270 } |
| 277 | 271 |
| 278 template<typename T> | 272 template<typename T> |
| 279 inline T* ThreadSpecific<T>::operator->() | 273 inline T* ThreadSpecific<T>::operator->() |
| 280 { | 274 { |
| 281 return operator T*(); | 275 return operator T*(); |
| 282 } | 276 } |
| 283 | 277 |
| 284 template<typename T> | 278 template<typename T> |
| 285 inline T& ThreadSpecific<T>::operator*() | 279 inline T& ThreadSpecific<T>::operator*() |
| 286 { | 280 { |
| 287 return *operator T*(); | 281 return *operator T*(); |
| 288 } | 282 } |
| 289 | 283 |
| 290 } // namespace WTF | 284 } // namespace WTF |
| 291 | 285 |
| 292 using WTF::ThreadSpecific; | 286 using WTF::ThreadSpecific; |
| 293 | 287 |
| 294 #endif // WTF_ThreadSpecific_h | 288 #endif // WTF_ThreadSpecific_h |
| OLD | NEW |