source: webkit/trunk/JavaScriptCore/wtf/ThreadingQt.cpp@ 38487

Last change on this file since 38487 was 38101, checked in by Darin Adler, 17 years ago

2008-11-03 Darin Adler <Darin Adler>

Reviewed by Tim Hatcher.

  • JavaScriptCore.exp: Changed to export functions rather than a global for the atomically initialized static mutex.
  • JavaScriptCore.xcodeproj/project.pbxproj: Added a script phase that runs the check-for-exit-time-destructors script.
  • wtf/MainThread.cpp: (WTF::mainThreadFunctionQueueMutex): Changed to leak an object rather than using an exit time destructor. (WTF::functionQueue): Ditto.
  • wtf/unicode/icu/CollatorICU.cpp: (WTF::cachedCollatorMutex): Ditto.
  • wtf/Threading.h: Changed other platforms to share the Windows approach where the mutex is internal and the functions are exported.
  • wtf/ThreadingGtk.cpp: (WTF::lockAtomicallyInitializedStaticMutex): Ditto. (WTF::unlockAtomicallyInitializedStaticMutex): Ditto.
  • wtf/ThreadingNone.cpp: (WTF::lockAtomicallyInitializedStaticMutex): Ditto. (WTF::unlockAtomicallyInitializedStaticMutex): Ditto.
  • wtf/ThreadingPthreads.cpp: (WTF::threadMapMutex): Changed to leak an object rather than using an exit time destructor. (WTF::lockAtomicallyInitializedStaticMutex): Mutex change. (WTF::unlockAtomicallyInitializedStaticMutex): Ditto. (WTF::threadMap): Changed to leak an object rather than using an exit time destructor.
  • wtf/ThreadingQt.cpp: (WTF::lockAtomicallyInitializedStaticMutex): Mutex change. (WTF::unlockAtomicallyInitializedStaticMutex): Ditto.
  • wtf/ThreadingWin.cpp: (WTF::lockAtomicallyInitializedStaticMutex): Added an assertion.
File size: 6.1 KB
Line 
1/*
2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2007 Justin Haygood ([email protected])
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29#include "config.h"
30#include "Threading.h"
31
32#include "HashMap.h"
33#include "MainThread.h"
34#include "MathExtras.h"
35
36#include <QCoreApplication>
37#include <QMutex>
38#include <QThread>
39#include <QWaitCondition>
40
41namespace WTF {
42
43class ThreadPrivate : public QThread {
44public:
45 ThreadPrivate(ThreadFunction entryPoint, void* data);
46 void run();
47 void* getReturnValue() { return m_returnValue; }
48private:
49 void* m_data;
50 ThreadFunction m_entryPoint;
51 void* m_returnValue;
52};
53
54ThreadPrivate::ThreadPrivate(ThreadFunction entryPoint, void* data)
55 : m_data(data)
56 , m_entryPoint(entryPoint)
57 , m_returnValue(0)
58{
59}
60
61void ThreadPrivate::run()
62{
63 m_returnValue = m_entryPoint(m_data);
64}
65
66
67static Mutex* atomicallyInitializedStaticMutex;
68
69static ThreadIdentifier mainThreadIdentifier;
70
71static Mutex& threadMapMutex()
72{
73 static Mutex mutex;
74 return mutex;
75}
76
77static HashMap<ThreadIdentifier, QThread*>& threadMap()
78{
79 static HashMap<ThreadIdentifier, QThread*> map;
80 return map;
81}
82
83static ThreadIdentifier establishIdentifierForThread(QThread*& thread)
84{
85 MutexLocker locker(threadMapMutex());
86
87 static ThreadIdentifier identifierCount = 1;
88
89 threadMap().add(identifierCount, thread);
90
91 return identifierCount++;
92}
93
94static void clearThreadForIdentifier(ThreadIdentifier id)
95{
96 MutexLocker locker(threadMapMutex());
97
98 ASSERT(threadMap().contains(id));
99
100 threadMap().remove(id);
101}
102
103static ThreadIdentifier identifierByQthreadHandle(QThread*& thread)
104{
105 MutexLocker locker(threadMapMutex());
106
107 HashMap<ThreadIdentifier, QThread*>::iterator i = threadMap().begin();
108 for (; i != threadMap().end(); ++i) {
109 if (i->second == thread)
110 return i->first;
111 }
112
113 return 0;
114}
115
116static QThread* threadForIdentifier(ThreadIdentifier id)
117{
118 MutexLocker locker(threadMapMutex());
119
120 return threadMap().get(id);
121}
122
123void initializeThreading()
124{
125 if (!atomicallyInitializedStaticMutex) {
126 atomicallyInitializedStaticMutex = new Mutex;
127 threadMapMutex();
128 wtf_random_init();
129 QThread* mainThread = QCoreApplication::instance()->thread();
130 mainThreadIdentifier = identifierByQthreadHandle(mainThread);
131 if (!mainThreadIdentifier)
132 mainThreadIdentifier = establishIdentifierForThread(mainThread);
133 initializeMainThread();
134 }
135}
136
137void lockAtomicallyInitializedStaticMutex()
138{
139 ASSERT(atomicallyInitializedStaticMutex);
140 atomicallyInitializedStaticMutex->lock();
141}
142
143void unlockAtomicallyInitializedStaticMutex()
144{
145 atomicallyInitializedStaticMutex->unlock();
146}
147
148ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*)
149{
150 ThreadPrivate* thread = new ThreadPrivate(entryPoint, data);
151 if (!thread) {
152 LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
153 return 0;
154 }
155 thread->start();
156
157 QThread* threadRef = static_cast<QThread*>(thread);
158
159 return establishIdentifierForThread(threadRef);
160}
161
162int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
163{
164 ASSERT(threadID);
165
166 QThread* thread = threadForIdentifier(threadID);
167
168 bool res = thread->wait();
169
170 clearThreadForIdentifier(threadID);
171 *result = static_cast<ThreadPrivate*>(thread)->getReturnValue();
172
173 return !res;
174}
175
176void detachThread(ThreadIdentifier)
177{
178}
179
180ThreadIdentifier currentThread()
181{
182 QThread* currentThread = QThread::currentThread();
183 if (ThreadIdentifier id = identifierByQthreadHandle(currentThread))
184 return id;
185 return establishIdentifierForThread(currentThread);
186}
187
188bool isMainThread()
189{
190 return currentThread() == mainThreadIdentifier;
191}
192
193Mutex::Mutex()
194 : m_mutex(new QMutex())
195{
196}
197
198Mutex::~Mutex()
199{
200 delete m_mutex;
201}
202
203void Mutex::lock()
204{
205 m_mutex->lock();
206}
207
208bool Mutex::tryLock()
209{
210 return m_mutex->tryLock();
211}
212
213void Mutex::unlock()
214{
215 m_mutex->unlock();
216}
217
218ThreadCondition::ThreadCondition()
219 : m_condition(new QWaitCondition())
220{
221}
222
223ThreadCondition::~ThreadCondition()
224{
225 delete m_condition;
226}
227
228void ThreadCondition::wait(Mutex& mutex)
229{
230 m_condition->wait(mutex.impl());
231}
232
233bool ThreadCondition::timedWait(Mutex& mutex, double secondsToWait)
234{
235 if (secondsToWait < 0.0) {
236 wait(mutex);
237 return true;
238 }
239
240 unsigned long millisecondsToWait = static_cast<unsigned long>(secondsToWait * 1000.0);
241 return m_condition->wait(mutex.impl(), millisecondsToWait);
242}
243
244void ThreadCondition::signal()
245{
246 m_condition->wakeOne();
247}
248
249void ThreadCondition::broadcast()
250{
251 m_condition->wakeAll();
252}
253
254} // namespace WebCore
Note: See TracBrowser for help on using the repository browser.