Changeset 39708 in webkit
- Timestamp:
- Jan 8, 2009 8:47:14 AM (15 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r39707 r39708 1 2009-01-08 Jian Li <jianli@chromium.org> 2 3 Reviewed by Alexey Proskuryakov. 4 5 Add Win32 implementation of ThreadSpecific. 6 https://bugs.webkit.org/show_bug.cgi?id=22614 7 8 * JavaScriptCore.vcproj/WTF/WTF.vcproj: 9 * wtf/ThreadSpecific.h: 10 (WTF::ThreadSpecific::ThreadSpecific): 11 (WTF::ThreadSpecific::~ThreadSpecific): 12 (WTF::ThreadSpecific::get): 13 (WTF::ThreadSpecific::set): 14 (WTF::ThreadSpecific::destroy): 15 * wtf/ThreadSpecificWin.cpp: Added. 16 (WTF::ThreadSpecificThreadExit): 17 * wtf/ThreadingWin.cpp: 18 (WTF::wtfThreadEntryPoint): 19 1 20 2009-01-08 Justin McPherson <justin.mcpherson@nokia.com> 2 21 -
trunk/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
r39487 r39708 1 <?xml version="1.0" encoding=" Windows-1252"?>1 <?xml version="1.0" encoding="windows-1251"?> 2 2 <VisualStudioProject 3 3 ProjectType="Visual C++" 4 Version="8 .00"4 Version="8,00" 5 5 Name="WTF" 6 6 ProjectGUID="{AA8A5A85-592B-4357-BC60-E0E91E026AF6}" … … 420 420 </File> 421 421 <File 422 RelativePath="..\..\wtf\Threading.cpp" 423 > 424 </File> 425 <File 422 426 RelativePath="..\..\wtf\Threading.h" 423 427 > 424 428 </File> 425 429 <File 426 RelativePath="..\..\wtf\Threading.cpp"427 >428 </File>429 <File430 430 RelativePath="..\..\wtf\ThreadingWin.cpp" 431 431 > … … 433 433 <File 434 434 RelativePath="..\..\wtf\ThreadSpecific.h" 435 > 436 </File> 437 <File 438 RelativePath="..\..\wtf\ThreadSpecificWin.cpp" 435 439 > 436 440 </File> -
trunk/JavaScriptCore/wtf/ThreadSpecific.h
r39672 r39708 1 1 /* 2 2 * Copyright (C) 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2009 Jian Li <jianli@chromium.org> 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 27 28 */ 28 29 30 /* Thread local storage is implemented by using either pthread API or Windows 31 * native API. There is subtle semantic discrepancy for the cleanup function 32 * implementation as noted below: 33 * @ In pthread implementation, the destructor function will be called 34 * repeatedly if there is still non-NULL value associated with the function. 35 * @ In Windows native implementation, the destructor function will be called 36 * only once. 37 * This semantic discrepancy does not impose any problem because nowhere in 38 * WebKit the repeated call bahavior is utilized. 39 */ 40 29 41 #ifndef WTF_ThreadSpecific_h 30 42 #define WTF_ThreadSpecific_h … … 32 44 #include <wtf/Noncopyable.h> 33 45 34 #if USE(PTHREADS) || PLATFORM(WIN) 35 // Windows currently doesn't use pthreads for basic threading, but implementing destructor functions is easier 36 // with pthreads, so we use it here. 46 #if USE(PTHREADS) 37 47 #include <pthread.h> 48 #elif PLATFORM(WIN_OS) 49 #include <windows.h> 38 50 #endif 39 51 40 52 namespace WTF { 53 54 #if !USE(PTHREADS) && PLATFORM(WIN_OS) 55 // ThreadSpecificThreadExit should be called each time when a thread is detached. 56 // This is done automatically for threads created with WTF::createThread. 57 void ThreadSpecificThreadExit(); 58 #endif 41 59 42 60 template<typename T> class ThreadSpecific : Noncopyable { … … 49 67 50 68 private: 69 #if !USE(PTHREADS) && PLATFORM(WIN_OS) 70 friend void ThreadSpecificThreadExit(); 71 #endif 72 51 73 T* get(); 52 74 void set(T*); 53 75 void static destroy(void* ptr); 54 76 55 #if USE(PTHREADS) || PLATFORM(WIN )77 #if USE(PTHREADS) || PLATFORM(WIN_OS) 56 78 struct Data : Noncopyable { 57 79 Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {} … … 59 81 T* value; 60 82 ThreadSpecific<T>* owner; 83 #if !USE(PTHREADS) 84 void (*destructor)(void*); 85 #endif 61 86 }; 62 87 #endif 88 89 #if USE(PTHREADS) 63 90 pthread_key_t m_key; 91 #elif PLATFORM(WIN_OS) 92 int m_index; 64 93 #endif 65 94 }; 66 95 67 #if USE(PTHREADS) || PLATFORM(WIN)96 #if USE(PTHREADS) 68 97 template<typename T> 69 98 inline ThreadSpecific<T>::ThreadSpecific() … … 94 123 } 95 124 125 #elif PLATFORM(WIN_OS) 126 127 // The maximum number of TLS keys that can be created. For simplification, we assume that: 128 // 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies. 129 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough. 130 const int kMaxTlsKeySize = 256; 131 132 extern long g_tls_key_count; 133 extern DWORD g_tls_keys[kMaxTlsKeySize]; 134 135 template<typename T> 136 inline ThreadSpecific<T>::ThreadSpecific() 137 : m_index(-1) 138 { 139 DWORD tls_key = TlsAlloc(); 140 if (tls_key == TLS_OUT_OF_INDEXES) 141 CRASH(); 142 143 m_index = InterlockedIncrement(&g_tls_key_count) - 1; 144 if (m_index >= kMaxTlsKeySize) 145 CRASH(); 146 g_tls_keys[m_index] = tls_key; 147 } 148 149 template<typename T> 150 inline ThreadSpecific<T>::~ThreadSpecific() 151 { 152 // Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached. 153 TlsFree(g_tls_keys[m_index]); 154 } 155 156 template<typename T> 157 inline T* ThreadSpecific<T>::get() 158 { 159 Data* data = static_cast<Data*>(TlsGetValue(g_tls_keys[m_index])); 160 return data ? data->value : 0; 161 } 162 163 template<typename T> 164 inline void ThreadSpecific<T>::set(T* ptr) 165 { 166 ASSERT(!get()); 167 Data* data = new Data(ptr, this); 168 data->destructor = &ThreadSpecific<T>::destroy; 169 TlsSetValue(g_tls_keys[m_index], data); 170 } 171 172 #else 173 #error ThreadSpecific is not implemented for this platform. 174 #endif 175 96 176 template<typename T> 97 177 inline void ThreadSpecific<T>::destroy(void* ptr) … … 99 179 Data* data = static_cast<Data*>(ptr); 100 180 181 #if USE(PTHREADS) 101 182 // We want get() to keep working while data destructor works, because it can be called indirectly by the destructor. 102 183 // Some pthreads implementations zero out the pointer before calling destroy(), so we temporarily reset it. 103 184 pthread_setspecific(data->owner->m_key, ptr); 185 #endif 186 104 187 data->value->~T(); 105 188 fastFree(data->value); 189 190 #if USE(PTHREADS) 106 191 pthread_setspecific(data->owner->m_key, 0); 107 delete data; 108 } 109 192 #elif PLATFORM(WIN_OS) 193 TlsSetValue(g_tls_keys[data->owner->m_index], 0); 110 194 #else 111 195 #error ThreadSpecific is not implemented for this platform. 112 196 #endif 197 198 delete data; 199 } 113 200 114 201 template<typename T> -
trunk/JavaScriptCore/wtf/ThreadingWin.cpp
r39604 r39708 65 65 66 66 #include "MainThread.h" 67 #if !USE(PTHREADS) && PLATFORM(WIN_OS) 68 #include "ThreadSpecific.h" 69 #endif 67 70 #include <process.h> 68 71 #include <windows.h> … … 175 178 176 179 void* result = invocation.function(invocation.data); 180 181 #if !USE(PTHREADS) && PLATFORM(WIN_OS) 182 // Do the TLS cleanup. 183 ThreadSpecificThreadExit(); 184 #endif 177 185 178 186 return reinterpret_cast<unsigned>(result);
Note: See TracChangeset
for help on using the changeset viewer.