JavaScriptCore/ChangeLog

 12009-04-27 Dmitry Titov <dimich@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 https://bugs.webkit.org/show_bug.cgi?id=25348
 6 Change WTF::ThreadIdentifier to be an actual (but wrapped) thread id, remove ThreadMap.
 7
 8 * JavaScriptCore.exp:
 9 * wtf/Threading.h:
 10 (WTF::ThreadIdentifier::ThreadIdentifier):
 11 (WTF::ThreadIdentifier::isValid):
 12 (WTF::ThreadIdentifier::invalidate):
 13 (WTF::ThreadIdentifier::platformId):
 14 ThreadIdentifier is now a class, containing a PlatformThreadIdentifier and
 15 methods that are used across the code on thread ids: construction, comparisons,
 16 check for 'valid' state etc. '0' is used as invalid id, which happens to just work
 17 with all platform-specific thread id implementations.
 18
 19 All the following files reflect the new ThreadIdentifier for each platform.
 20 We remove ThreadMap and threadMapMutex from all of them, remove the functions that
 21 populated/searched/cleared the map and add platform-specific comparison operators
 22 for ThreadIdentifier:
 23
 24 * wtf/ThreadingGtk.cpp:
 25 (WTF::ThreadIdentifier::operator==):
 26 (WTF::ThreadIdentifier::operator!=):
 27 (WTF::initializeThreading):
 28 (WTF::createThreadInternal):
 29 (WTF::waitForThreadCompletion):
 30 (WTF::currentThread):
 31
 32 * wtf/ThreadingNone.cpp:
 33 (WTF::ThreadIdentifier::operator==):
 34 (WTF::ThreadIdentifier::operator!=):
 35
 36 * wtf/ThreadingPthreads.cpp:
 37 (WTF::ThreadIdentifier::operator==):
 38 (WTF::ThreadIdentifier::operator!=):
 39 (WTF::initializeThreading):
 40 (WTF::createThreadInternal):
 41 (WTF::waitForThreadCompletion):
 42 (WTF::detachThread):
 43 (WTF::currentThread):
 44
 45 * wtf/ThreadingQt.cpp:
 46 (WTF::ThreadIdentifier::operator==):
 47 (WTF::ThreadIdentifier::operator!=):
 48 (WTF::initializeThreading):
 49 (WTF::createThreadInternal):
 50 (WTF::waitForThreadCompletion):
 51 (WTF::currentThread):
 52
 53 * wtf/ThreadingWin.cpp:
 54 (WTF::ThreadIdentifier::operator==):
 55 (WTF::ThreadIdentifier::operator!=):
 56 (WTF::initializeThreading):
 57 (WTF::createThreadInternal):
 58 (WTF::waitForThreadCompletion):
 59 (WTF::detachThread):
 60 (WTF::currentThread):
 61
1622009-04-27 Gavin Barraclough <barraclough@apple.com>
263
364 Reviewed by Maciej Stachowiak.

JavaScriptCore/JavaScriptCore.exp

@@__ZN3WTF11currentTimeEv
274274__ZN3WTF11fastReallocEPvm
275275__ZN3WTF12createThreadEPFPvS0_ES0_
276276__ZN3WTF12createThreadEPFPvS0_ES0_PKc
277 __ZN3WTF12detachThreadEj
 277__ZN3WTF12detachThreadENS_16ThreadIdentifierE
278278__ZN3WTF12isMainThreadEv
279279__ZN3WTF12randomNumberEv
280280__ZN3WTF13currentThreadEv

@@__ZN3WTF21RefCountedLeakCounter9decrementEv
295295__ZN3WTF21RefCountedLeakCounter9incrementEv
296296__ZN3WTF21RefCountedLeakCounterC1EPKc
297297__ZN3WTF21RefCountedLeakCounterD1Ev
298 __ZN3WTF23waitForThreadCompletionEjPPv
 298__ZN3WTF23waitForThreadCompletionENS_16ThreadIdentifierEPPv
299299__ZN3WTF27releaseFastMallocFreeMemoryEv
300300__ZN3WTF28setMainThreadCallbacksPausedEb
301301__ZN3WTF36lockAtomicallyInitializedStaticMutexEv

@@__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
357357__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
358358__ZNK3JSC9HashTable11deleteTableEv
359359__ZNK3WTF8Collator7collateEPKtmS2_m
 360__ZNK3WTF16ThreadIdentifier7isValidEv
 361__ZNK3WTF16ThreadIdentifiereqERKS0_
 362__ZNK3WTF16ThreadIdentifierneERKS0_
360363__ZTVN3JSC12StringObjectE
361364__ZTVN3JSC14JSGlobalObjectE
362365__ZTVN3JSC15JSWrapperObjectE

JavaScriptCore/wtf/Threading.h

8585#include <wtf/GOwnPtr.h>
8686typedef struct _GMutex GMutex;
8787typedef struct _GCond GCond;
 88typedef struct _GThread GThread;
8889#endif
8990
9091#if PLATFORM(QT)
9192#include <qglobal.h>
9293QT_BEGIN_NAMESPACE
9394class QMutex;
 95class QThread;
9496class QWaitCondition;
9597QT_END_NAMESPACE
9698#endif

@@QT_END_NAMESPACE
105107
106108namespace WTF {
107109
108 typedef uint32_t ThreadIdentifier;
109 typedef void* (*ThreadFunction)(void* argument);
110 
111 // Returns 0 if thread creation failed.
112 // The thread name must be a literal since on some platforms it's passed in to the thread.
113 ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
114 
115 // Internal platform-specific createThread implementation.
116 ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
117 
118 // Called in the thread during initialization.
119 // Helpful for platforms where the thread name must be set from within the thread.
120 void setThreadNameInternal(const char* threadName);
121 
122 ThreadIdentifier currentThread();
123 bool isMainThread();
124 int waitForThreadCompletion(ThreadIdentifier, void**);
125 void detachThread(ThreadIdentifier);
126 
127110#if USE(PTHREADS)
128111typedef pthread_mutex_t PlatformMutex;
129112typedef pthread_cond_t PlatformCondition;
 113typedef pthread_t PlatformThreadIdentifier;
130114#elif PLATFORM(GTK)
131115typedef GOwnPtr<GMutex> PlatformMutex;
132116typedef GOwnPtr<GCond> PlatformCondition;
 117typedef GThread* PlatformThreadIdentifier;
133118#elif PLATFORM(QT)
134119typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;
135120typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;
 121typedef QT_PREPEND_NAMESPACE(QThread)* PlatformThreadIdentifier;
136122#elif PLATFORM(WIN_OS)
137123struct PlatformMutex {
138124 CRITICAL_SECTION m_internalMutex;

@@struct PlatformCondition {
149135 bool timedWait(PlatformMutex&, DWORD durationMilliseconds);
150136 void signal(bool unblockAll);
151137};
 138typedef unsigned PlatformThreadIdentifier;
152139#else
153140typedef void* PlatformMutex;
154141typedef void* PlatformCondition;
155142#endif
156143
 144// Platform-independent wrapper of ThreadId. Assignable and copyable.
 145// It happens that for all current implementations '0' works fine as 'invalid value'.
 146// Comparing is delegated to the platform implementations because it needs to
 147// compare in a platform-dependent way.
 148class ThreadIdentifier {
 149public:
 150 ThreadIdentifier()
 151 : m_platformId(0)
 152 {
 153 ASSERT(!isValid());
 154 }
 155
 156 explicit ThreadIdentifier(PlatformThreadIdentifier platformId)
 157 : m_platformId(platformId)
 158 {
 159 ASSERT(isValid());
 160 }
 161
 162 ThreadIdentifier(const ThreadIdentifier& another)
 163 : m_platformId(another.m_platformId)
 164 {
 165 }
 166
 167 bool isValid() const { return m_platformId; }
 168 void invalidate() { m_platformId = 0; }
 169
 170 bool operator==(const ThreadIdentifier&) const;
 171 bool operator!=(const ThreadIdentifier&) const;
 172
 173 PlatformThreadIdentifier platformId() const { return m_platformId; }
 174
 175private:
 176 PlatformThreadIdentifier m_platformId;
 177};
 178
 179typedef void* (*ThreadFunction)(void* argument);
 180
 181// Returns invalid identifier if thread creation failed.
 182// The thread name must be a literal since on some platforms it's passed in to the thread.
 183ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
 184
 185// Internal platform-specific createThread implementation.
 186ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
 187
 188// Called in the thread during initialization.
 189// Helpful for platforms where the thread name must be set from within the thread.
 190void setThreadNameInternal(const char* threadName);
 191
 192ThreadIdentifier currentThread();
 193bool isMainThread();
 194int waitForThreadCompletion(ThreadIdentifier, void**);
 195void detachThread(ThreadIdentifier);
 196
157197class Mutex : Noncopyable {
158198public:
159199 Mutex();

JavaScriptCore/wtf/ThreadingNone.cpp

3232
3333namespace WTF {
3434
 35bool ThreadIdentifier::operator==(const ThreadIdentifier&) const { return true; }
 36bool ThreadIdentifier::operator!=(const ThreadIdentifier&) const { return false; }
 37
3538void initializeThreading() { }
3639ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return 0; }
3740void setThreadNameInternal(const char*) { }

JavaScriptCore/wtf/ThreadingPthreads.cpp

4848
4949namespace WTF {
5050
51 typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
 51bool ThreadIdentifier::operator==(const ThreadIdentifier& another) const
 52{
 53 return pthread_equal(m_platformId, another.m_platformId);
 54}
 55
 56bool ThreadIdentifier::operator!=(const ThreadIdentifier& another) const
 57{
 58 return !pthread_equal(m_platformId, another.m_platformId);
 59}
5260
5361static Mutex* atomicallyInitializedStaticMutex;
5462

@@static Mutex* atomicallyInitializedStaticMutex;
5664static ThreadIdentifier mainThreadIdentifier; // The thread that was the first to call initializeThreading(), which must be the main thread.
5765#endif
5866
59 static Mutex& threadMapMutex()
60 {
61  DEFINE_STATIC_LOCAL(Mutex, mutex, ());
62  return mutex;
63 }
64 
6567void initializeThreading()
6668{
6769 if (!atomicallyInitializedStaticMutex) {
6870 atomicallyInitializedStaticMutex = new Mutex;
69  threadMapMutex();
7071 initializeRandomNumberGenerator();
7172#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM)
7273 mainThreadIdentifier = currentThread();

@@void unlockAtomicallyInitializedStaticMutex()
8687 atomicallyInitializedStaticMutex->unlock();
8788}
8889
89 static ThreadMap& threadMap()
90 {
91  DEFINE_STATIC_LOCAL(ThreadMap, map, ());
92  return map;
93 }
94 
95 static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle)
96 {
97  MutexLocker locker(threadMapMutex());
98 
99  ThreadMap::iterator i = threadMap().begin();
100  for (; i != threadMap().end(); ++i) {
101  if (pthread_equal(i->second, pthreadHandle))
102  return i->first;
103  }
104 
105  return 0;
106 }
107 
108 static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle)
109 {
110  ASSERT(!identifierByPthreadHandle(pthreadHandle));
111 
112  MutexLocker locker(threadMapMutex());
113 
114  static ThreadIdentifier identifierCount = 1;
115 
116  threadMap().add(identifierCount, pthreadHandle);
117 
118  return identifierCount++;
119 }
120 
121 static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id)
122 {
123  MutexLocker locker(threadMapMutex());
124 
125  return threadMap().get(id);
126 }
127 
128 static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
129 {
130  MutexLocker locker(threadMapMutex());
131 
132  ASSERT(threadMap().contains(id));
133 
134  threadMap().remove(id);
135 }
136 
13790#if PLATFORM(ANDROID)
13891// On the Android platform, threads must be registered with the VM before they run.
13992struct ThreadData {

@@ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
164117
165118 if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast<void*>(threadData))) {
166119 LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
167  return 0;
 120 return ThreadIdentifier();
168121 }
169  return establishIdentifierForPthreadHandle(threadHandle);
 122 return ThreadIdentifier(threadHandle);
170123}
171124#else
172125ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)

@@ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
174127 pthread_t threadHandle;
175128 if (pthread_create(&threadHandle, 0, entryPoint, data)) {
176129 LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
177  return 0;
 130 return ThreadIdentifier();
178131 }
179132
180  return establishIdentifierForPthreadHandle(threadHandle);
 133 return ThreadIdentifier(threadHandle);
181134}
182135#endif
183136

@@void setThreadNameInternal(const char* threadName)
192145
193146int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
194147{
195  ASSERT(threadID);
 148 ASSERT(threadID.isValid());
196149
197  pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
 150 pthread_t pthreadHandle = threadID.platformId();
198151
199152 int joinResult = pthread_join(pthreadHandle, result);
200153 if (joinResult == EDEADLK)
201  LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
 154 LOG_ERROR("ThreadIdentifier %p was found to be deadlocked trying to quit", pthreadHandle);
202155
203  clearPthreadHandleForIdentifier(threadID);
204156 return joinResult;
205157}
206158
207159void detachThread(ThreadIdentifier threadID)
208160{
209  ASSERT(threadID);
 161 ASSERT(threadID.isValid());
210162
211  pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
 163 pthread_t pthreadHandle = threadID.platformId();
212164
213165 pthread_detach(pthreadHandle);
214 
215  clearPthreadHandleForIdentifier(threadID);
216166}
217167
218168ThreadIdentifier currentThread()
219169{
220  pthread_t currentThread = pthread_self();
221  if (ThreadIdentifier id = identifierByPthreadHandle(currentThread))
222  return id;
223  return establishIdentifierForPthreadHandle(currentThread);
 170 return ThreadIdentifier(pthread_self());
224171}
225172
226173bool isMainThread()

JavaScriptCore/wtf/ThreadingWin.cpp

9898
9999namespace WTF {
100100
 101bool ThreadIdentifier::operator==(const ThreadIdentifier& another) const
 102{
 103 return m_platformId == another.m_platformId;
 104}
 105
 106bool ThreadIdentifier::operator!=(const ThreadIdentifier& another) const
 107{
 108 return m_platformId != another.m_platformId;
 109}
 110
101111// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
102112static const DWORD MS_VC_EXCEPTION = 0x406D1388;
103113

@@void unlockAtomicallyInitializedStaticMutex()
139149
140150static ThreadIdentifier mainThreadIdentifier;
141151
142 static Mutex& threadMapMutex()
143 {
144  static Mutex mutex;
145  return mutex;
146 }
147 
148152void initializeThreading()
149153{
150154 if (!atomicallyInitializedStaticMutex) {
151155 atomicallyInitializedStaticMutex = new Mutex;
152  threadMapMutex();
153156 initializeRandomNumberGenerator();
154157 initializeMainThread();
155158 mainThreadIdentifier = currentThread();

@@void initializeThreading()
157160 }
158161}
159162
160 static HashMap<DWORD, HANDLE>& threadMap()
161 {
162  static HashMap<DWORD, HANDLE> map;
163  return map;
164 }
165 
166 static void storeThreadHandleByIdentifier(DWORD threadID, HANDLE threadHandle)
167 {
168  MutexLocker locker(threadMapMutex());
169  ASSERT(!threadMap().contains(threadID));
170  threadMap().add(threadID, threadHandle);
171 }
172 
173 static HANDLE threadHandleForIdentifier(ThreadIdentifier id)
174 {
175  MutexLocker locker(threadMapMutex());
176  return threadMap().get(id);
177 }
178 
179 static void clearThreadHandleForIdentifier(ThreadIdentifier id)
180 {
181  MutexLocker locker(threadMapMutex());
182  ASSERT(threadMap().contains(id));
183  threadMap().remove(id);
184 }
185 
186163struct ThreadFunctionInvocation {
187164 ThreadFunctionInvocation(ThreadFunction function, void* data) : function(function), data(data) {}
188165

@@static unsigned __stdcall wtfThreadEntryPoint(void* param)
208185ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char* threadName)
209186{
210187 unsigned threadIdentifier = 0;
211  ThreadIdentifier threadID = 0;
212188 ThreadFunctionInvocation* invocation = new ThreadFunctionInvocation(entryPoint, data);
213189 HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation, 0, &threadIdentifier));
214190 if (!threadHandle) {
215191 LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, errno);
216  return 0;
 192 return ThreadIdentifier();
217193 }
218194
219  threadID = static_cast<ThreadIdentifier>(threadIdentifier);
220  storeThreadHandleByIdentifier(threadIdentifier, threadHandle);
221 
222  return threadID;
 195 return ThreadIdentifier(threadIdentifier);
223196}
224197
225198int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
226199{
227  ASSERT(threadID);
 200 ASSERT(threadID.isValid());
228201
229  HANDLE threadHandle = threadHandleForIdentifier(threadID);
 202 HANDLE threadHandle = threadID.platformId();
230203 if (!threadHandle)
231204 LOG_ERROR("ThreadIdentifier %u did not correspond to an active thread when trying to quit", threadID);
232205
233206 DWORD joinResult = WaitForSingleObject(threadHandle, INFINITE);
234207 if (joinResult == WAIT_FAILED)
235  LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
 208 LOG_ERROR("ThreadIdentifier %p was found to be deadlocked trying to quit", threadHandle);
236209
237210 CloseHandle(threadHandle);
238  clearThreadHandleForIdentifier(threadID);
239211
240212 return joinResult;
241213}
242214
243215void detachThread(ThreadIdentifier threadID)
244216{
245  ASSERT(threadID);
 217 ASSERT(threadID.isValid());
246218
247  HANDLE threadHandle = threadHandleForIdentifier(threadID);
 219 HANDLE threadHandle = threadID.platformId();
248220 if (threadHandle)
249221 CloseHandle(threadHandle);
250  clearThreadHandleForIdentifier(threadID);
251222}
252223
253224ThreadIdentifier currentThread()
254225{
255  return static_cast<ThreadIdentifier>(GetCurrentThreadId());
 226 return ThreadIdentifier(GetCurrentThreadId());
256227}
257228
258229bool isMainThread()

JavaScriptCore/wtf/gtk/ThreadingGtk.cpp

4242
4343namespace WTF {
4444
45 static Mutex* atomicallyInitializedStaticMutex;
46 
47 static ThreadIdentifier mainThreadIdentifier;
 45bool ThreadIdentifier::operator==(const ThreadIdentifier& another) const
 46{
 47 return m_platformId == another.m_platformId;
 48}
4849
49 static Mutex& threadMapMutex()
 50bool ThreadIdentifier::operator!=(const ThreadIdentifier& another) const
5051{
51  static Mutex mutex;
52  return mutex;
 52 return m_platformId != another.m_platformId;
5353}
5454
 55static Mutex* atomicallyInitializedStaticMutex;
 56
 57static ThreadIdentifier mainThreadIdentifier;
 58
5559void initializeThreading()
5660{
5761 if (!g_thread_supported())

@@void initializeThreading()
6064
6165 if (!atomicallyInitializedStaticMutex) {
6266 atomicallyInitializedStaticMutex = new Mutex;
63  threadMapMutex();
6467 initializeRandomNumberGenerator();
6568 mainThreadIdentifier = currentThread();
6669 initializeMainThread();

@@void unlockAtomicallyInitializedStaticMutex()
7881 atomicallyInitializedStaticMutex->unlock();
7982}
8083
81 static HashMap<ThreadIdentifier, GThread*>& threadMap()
82 {
83  static HashMap<ThreadIdentifier, GThread*> map;
84  return map;
85 }
86 
87 static ThreadIdentifier identifierByGthreadHandle(GThread*& thread)
88 {
89  MutexLocker locker(threadMapMutex());
90 
91  HashMap<ThreadIdentifier, GThread*>::iterator i = threadMap().begin();
92  for (; i != threadMap().end(); ++i) {
93  if (i->second == thread)
94  return i->first;
95  }
96 
97  return 0;
98 }
99 
100 static ThreadIdentifier establishIdentifierForThread(GThread*& thread)
101 {
102  ASSERT(!identifierByGthreadHandle(thread));
103 
104  MutexLocker locker(threadMapMutex());
105 
106  static ThreadIdentifier identifierCount = 1;
107 
108  threadMap().add(identifierCount, thread);
109 
110  return identifierCount++;
111 }
112 
113 static GThread* threadForIdentifier(ThreadIdentifier id)
114 {
115  MutexLocker locker(threadMapMutex());
116 
117  return threadMap().get(id);
118 }
119 
120 static void clearThreadForIdentifier(ThreadIdentifier id)
121 {
122  MutexLocker locker(threadMapMutex());
123 
124  ASSERT(threadMap().contains(id));
125 
126  threadMap().remove(id);
127 }
128 
12984ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
13085{
13186 GThread* thread;
13287 if (!(thread = g_thread_create(entryPoint, data, TRUE, 0))) {
13388 LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
134  return 0;
 89 return ThreadIdentifier();
13590 }
13691
137  ThreadIdentifier threadID = establishIdentifierForThread(thread);
138  return threadID;
 92 return ThreadIdentifier(thread);
13993}
14094
14195void setThreadNameInternal(const char*)

@@void setThreadNameInternal(const char*)
14498
14599int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
146100{
147  ASSERT(threadID);
 101 ASSERT(threadID.isValid());
148102
149  GThread* thread = threadForIdentifier(threadID);
 103 GThread* thread = threadID.platformId();
150104
151105 void* joinResult = g_thread_join(thread);
152106 if (result)
153107 *result = joinResult;
154108
155  clearThreadForIdentifier(threadID);
156109 return 0;
157110}
158111

@@void detachThread(ThreadIdentifier)
162115
163116ThreadIdentifier currentThread()
164117{
165  GThread* currentThread = g_thread_self();
166  if (ThreadIdentifier id = identifierByGthreadHandle(currentThread))
167  return id;
168  return establishIdentifierForThread(currentThread);
 118 return ThreadIdentifier(g_thread_self());
169119}
170120
171121bool isMainThread()

JavaScriptCore/wtf/qt/ThreadingQt.cpp

4141
4242namespace WTF {
4343
 44bool ThreadIdentifier::operator==(const ThreadIdentifier& another) const
 45{
 46 return m_platformId == another.m_platformId;
 47}
 48
 49bool ThreadIdentifier::operator!=(const ThreadIdentifier& another) const
 50{
 51 return m_platformId != another.m_platformId;
 52}
 53
4454class ThreadPrivate : public QThread {
4555public:
4656 ThreadPrivate(ThreadFunction entryPoint, void* data);

@@static Mutex* atomicallyInitializedStaticMutex;
6979
7080static ThreadIdentifier mainThreadIdentifier;
7181
72 static Mutex& threadMapMutex()
73 {
74  static Mutex mutex;
75  return mutex;
76 }
77 
78 static HashMap<ThreadIdentifier, QThread*>& threadMap()
79 {
80  static HashMap<ThreadIdentifier, QThread*> map;
81  return map;
82 }
83 
84 static ThreadIdentifier identifierByQthreadHandle(QThread*& thread)
85 {
86  MutexLocker locker(threadMapMutex());
87 
88  HashMap<ThreadIdentifier, QThread*>::iterator i = threadMap().begin();
89  for (; i != threadMap().end(); ++i) {
90  if (i->second == thread)
91  return i->first;
92  }
93 
94  return 0;
95 }
96 
97 static ThreadIdentifier establishIdentifierForThread(QThread*& thread)
98 {
99  ASSERT(!identifierByQthreadHandle(thread));
100 
101  MutexLocker locker(threadMapMutex());
102 
103  static ThreadIdentifier identifierCount = 1;
104 
105  threadMap().add(identifierCount, thread);
106 
107  return identifierCount++;
108 }
109 
110 static void clearThreadForIdentifier(ThreadIdentifier id)
111 {
112  MutexLocker locker(threadMapMutex());
113 
114  ASSERT(threadMap().contains(id));
115 
116  threadMap().remove(id);
117 }
118 
119 static QThread* threadForIdentifier(ThreadIdentifier id)
120 {
121  MutexLocker locker(threadMapMutex());
122 
123  return threadMap().get(id);
124 }
125 
12682void initializeThreading()
12783{
12884 if (!atomicallyInitializedStaticMutex) {
12985 atomicallyInitializedStaticMutex = new Mutex;
130  threadMapMutex();
13186 initializeRandomNumberGenerator();
132  QThread* mainThread = QCoreApplication::instance()->thread();
133  mainThreadIdentifier = identifierByQthreadHandle(mainThread);
134  if (!mainThreadIdentifier)
135  mainThreadIdentifier = establishIdentifierForThread(mainThread);
 87 mainThreadIdentifier = ThreadIdentifier(QCoreApplication::instance()->thread());
13688 initializeMainThread();
13789 }
13890}

@@ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
153105 ThreadPrivate* thread = new ThreadPrivate(entryPoint, data);
154106 if (!thread) {
155107 LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
156  return 0;
 108 return ThreadIdentifier();
157109 }
158110 thread->start();
159111
160112 QThread* threadRef = static_cast<QThread*>(thread);
161113
162  return establishIdentifierForThread(threadRef);
 114 return ThreadIdentifier(threadRef);
163115}
164116
165117void setThreadNameInternal(const char*)

@@void setThreadNameInternal(const char*)
168120
169121int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
170122{
171  ASSERT(threadID);
 123 ASSERT(threadID.IsValid());
172124
173  QThread* thread = threadForIdentifier(threadID);
 125 QThread* thread = threadID.platformId();
174126
175127 bool res = thread->wait();
176128
177  clearThreadForIdentifier(threadID);
178129 if (result)
179130 *result = static_cast<ThreadPrivate*>(thread)->getReturnValue();
180131

@@void detachThread(ThreadIdentifier)
187138
188139ThreadIdentifier currentThread()
189140{
190  QThread* currentThread = QThread::currentThread();
191  if (ThreadIdentifier id = identifierByQthreadHandle(currentThread))
192  return id;
193  return establishIdentifierForThread(currentThread);
 141 return ThreadIdentifier(QThread::currentThread());
194142}
195143
196144bool isMainThread()

WebCore/ChangeLog

 12009-04-27 Dmitry Titov <dimich@chromium.org>
 2
 3 Reviewed by NOBODY (OOPS!).
 4
 5 https://bugs.webkit.org/show_bug.cgi?id=25348
 6 Change WTF::ThreadIdentifier to be an actual (but wrapped) thread id, remove ThreadMap.
 7
 8 Most of the change is in WTF.
 9 Unless noted, all the following files changed to use the new ThreadIdentifier::isValid()
 10 method instead of just doing 'if(m_threadID)' kind of checks, since ThreadIdentifier
 11 is now a class rather then an integer.
 12
 13 * dom/XMLTokenizerLibxml2.cpp:
 14 (WebCore::libxmlLoaderThread): use DEFINE_STATIC_LOCAL and accessor function for static thread id,
 15 since now ThreadIdentifier needs construction and we avoid having global initializers.
 16 (WebCore::matchFunc): use the new accessor function.
 17 (WebCore::openFunc): ditto.
 18 (WebCore::createStringParser): ditto.
 19 (WebCore::createMemoryParser): ditto.
 20 * loader/icon/IconDatabase.cpp:
 21 (WebCore::IconDatabase::open):
 22 * storage/DatabaseThread.cpp:
 23 (WebCore::DatabaseThread::start):
 24 (WebCore::DatabaseThread::databaseThread): remove m_threadID from debug output.
 25 * storage/LocalStorageThread.cpp:
 26 (WebCore::LocalStorageThread::start):
 27 (WebCore::LocalStorageThread::scheduleImport):
 28 (WebCore::LocalStorageThread::scheduleSync):
 29 (WebCore::LocalStorageThread::terminate):
 30 * workers/WorkerThread.cpp:
 31 (WebCore::WorkerThread::start):
 32
1332009-04-27 Eric Roman <eroman@chromium.org>
234
335 Reviewed by Darin Fisher.

WebCore/dom/XMLTokenizerLibxml2.cpp

@@private:
326326// --------------------------------
327327
328328static int globalDescriptor = 0;
329 static ThreadIdentifier libxmlLoaderThread = 0;
 329
 330static ThreadIdentifier& libxmlLoaderThread() {
 331 DEFINE_STATIC_LOCAL(ThreadIdentifier, staticLibxmlLoaderThread, ());
 332 return staticLibxmlLoaderThread;
 333}
330334
331335static int matchFunc(const char*)
332336{
333337 // Only match loads initiated due to uses of libxml2 from within XMLTokenizer to avoid
334338 // interfering with client applications that also use libxml2. http://bugs.webkit.org/show_bug.cgi?id=17353
335  return XMLTokenizerScope::currentDocLoader && currentThread() == libxmlLoaderThread;
 339 return XMLTokenizerScope::currentDocLoader && currentThread() == libxmlLoaderThread();
336340}
337341
338342class OffsetBuffer {

@@static bool shouldAllowExternalLoad(const KURL& url)
393397static void* openFunc(const char* uri)
394398{
395399 ASSERT(XMLTokenizerScope::currentDocLoader);
396  ASSERT(currentThread() == libxmlLoaderThread);
 400 ASSERT(currentThread() == libxmlLoaderThread());
397401
398402 KURL url(KURL(), uri);
399403

@@static xmlParserCtxtPtr createStringParser(xmlSAXHandlerPtr handlers, void* user
462466 xmlInitParser();
463467 xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc);
464468 xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc);
465  libxmlLoaderThread = currentThread();
 469 libxmlLoaderThread() = currentThread();
466470 didInit = true;
467471 }
468472

@@static xmlParserCtxtPtr createMemoryParser(xmlSAXHandlerPtr handlers, void* user
484488 xmlInitParser();
485489 xmlRegisterInputCallbacks(matchFunc, openFunc, readFunc, closeFunc);
486490 xmlRegisterOutputCallbacks(matchFunc, openFunc, writeFunc, closeFunc);
487  libxmlLoaderThread = currentThread();
 491 libxmlLoaderThread() = currentThread();
488492 didInit = true;
489493 }
490494

WebCore/loader/icon/IconDatabase.cpp

@@bool IconDatabase::open(const String& databasePath)
135135 // completes and m_syncThreadRunning is properly set
136136 m_syncLock.lock();
137137 m_syncThread = createThread(IconDatabase::iconDatabaseSyncThreadStart, this, "WebCore: IconDatabase");
138  m_syncThreadRunning = m_syncThread;
 138 m_syncThreadRunning = m_syncThread.isValid();
139139 m_syncLock.unlock();
140  if (!m_syncThread)
141  return false;
142  return true;
 140
 141 return m_syncThreadRunning;
143142}
144143
145144void IconDatabase::close()

WebCore/platform/sql/SQLiteDatabase.cpp

@@SQLiteDatabase::SQLiteDatabase()
4747 : m_db(0)
4848 , m_pageSize(-1)
4949 , m_transactionInProgress(false)
50  , m_openingThread(0)
5150{
5251}
5352

@@void SQLiteDatabase::close()
8988 m_db = 0;
9089 }
9190
92  m_openingThread = 0;
 91 m_openingThread.invalidate();
9392}
9493
9594void SQLiteDatabase::setFullsync(bool fsync)

WebCore/storage/DatabaseThread.cpp

3737namespace WebCore {
3838
3939DatabaseThread::DatabaseThread()
40  : m_threadID(0)
4140{
4241 m_selfRef = this;
4342}

@@bool DatabaseThread::start()
5150{
5251 MutexLocker lock(m_threadCreationMutex);
5352
54  if (m_threadID)
 53 if (m_threadID.isValid())
5554 return true;
5655
5756 m_threadID = createThread(DatabaseThread::databaseThreadStart, this, "WebCore: Database");
5857
59  return m_threadID;
 58 return m_threadID.isValid();
6059}
6160
6261void DatabaseThread::requestTermination()

@@void* DatabaseThread::databaseThread()
9594 pool.cycle();
9695 }
9796
98  LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());
 97 LOG(StorageAPI, "About to detach thread and clear the ref to DatabaseThread %p, which currently has %i ref(s)", this, refCount());
9998
10099 // Detach the thread so its resources are no longer of any concern to anyone else
101100 detachThread(m_threadID);

WebCore/storage/LocalStorageThread.cpp

@@PassRefPtr<LocalStorageThread> LocalStorageThread::create()
3838}
3939
4040LocalStorageThread::LocalStorageThread()
41  : m_threadID(0)
4241{
4342 m_selfRef = this;
4443}

@@bool LocalStorageThread::start()
4746{
4847 MutexLocker lock(m_threadCreationMutex);
4948
50  if (m_threadID)
51  return true;
 49 if (!m_threadID.isValid())
 50 m_threadID = createThread(LocalStorageThread::localStorageThreadStart, this, "WebCore: LocalStorage");
5251
53  m_threadID = createThread(LocalStorageThread::localStorageThreadStart, this, "WebCore: LocalStorage");
54 
55  return m_threadID;
 52 return m_threadID.isValid();
5653}
5754
5855void* LocalStorageThread::localStorageThreadStart(void* thread)

@@void* LocalStorageThread::localStorageThread()
7774
7875 // Detach the thread so its resources are no longer of any concern to anyone else
7976 detachThread(m_threadID);
80  m_threadID = 0;
 77 m_threadID.invalidate();
8178
8279 // Clear the self refptr, possibly resulting in deletion
8380 m_selfRef = 0;

@@void* LocalStorageThread::localStorageThread()
8784
8885void LocalStorageThread::scheduleImport(PassRefPtr<LocalStorage> storage)
8986{
90  ASSERT(!m_queue.killed() && m_threadID);
 87 ASSERT(!m_queue.killed() && m_threadID.isValid());
9188 m_queue.append(LocalStorageTask::createImport(storage));
9289}
9390
9491void LocalStorageThread::scheduleSync(PassRefPtr<LocalStorage> storage)
9592{
96  ASSERT(!m_queue.killed() && m_threadID);
 93 ASSERT(!m_queue.killed() && m_threadID.isValid());
9794 m_queue.append(LocalStorageTask::createSync(storage));
9895}
9996
10097void LocalStorageThread::scheduleImport(PassRefPtr<LocalStorageArea> area)
10198{
102  ASSERT(!m_queue.killed() && m_threadID);
 99 ASSERT(!m_queue.killed() && m_threadID.isValid());
103100 m_queue.append(LocalStorageTask::createImport(area));
104101}
105102
106103void LocalStorageThread::scheduleSync(PassRefPtr<LocalStorageArea> area)
107104{
108  ASSERT(!m_queue.killed() && m_threadID);
 105 ASSERT(!m_queue.killed() && m_threadID.isValid());
109106 m_queue.append(LocalStorageTask::createSync(area));
110107}
111108

@@void LocalStorageThread::terminate()
115112
116113 // Ideally we'd never be killing a thread that wasn't live, so ASSERT it.
117114 // But if we do in a release build, make sure to not wait on a condition that will never get signalled
118  ASSERT(!m_queue.killed() && m_threadID);
119  if (!m_threadID)
 115 ASSERT(!m_queue.killed() && m_threadID.isValid());
 116 if (!m_threadID.isValid())
120117 return;
121118
122119 MutexLocker locker(m_terminateLock);

WebCore/workers/WorkerThread.cpp

@@PassRefPtr<WorkerThread> WorkerThread::create(const KURL& scriptURL, const Strin
6868}
6969
7070WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerObjectProxy* workerObjectProxy)
71  : m_threadID(0)
72  , m_workerObjectProxy(workerObjectProxy)
 71 : m_workerObjectProxy(workerObjectProxy)
7372 , m_startupData(WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode))
7473{
7574}

@@bool WorkerThread::start()
8382 // Mutex protection is necessary to ensure that m_threadID is initialized when the thread starts.
8483 MutexLocker lock(m_threadCreationMutex);
8584
86  if (m_threadID)
87  return true;
 85 if (!m_threadID.isValid())
 86 m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore: Worker");
8887
89  m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore: Worker");
90 
91  return m_threadID;
 88 return m_threadID.isValid();
9289}
9390
9491void* WorkerThread::workerThreadStart(void* thread)