source: webkit/trunk/JavaScriptCore/wtf/ThreadingGtk.cpp@ 38975

Last change on this file since 38975 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.
  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1/*
2 * Copyright (C) 2007, 2008 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 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
30#include "config.h"
31#include "Threading.h"
32
33#if !USE(PTHREADS)
34
35#include "HashMap.h"
36#include "MainThread.h"
37#include "MathExtras.h"
38
39#include <glib.h>
40
41namespace WTF {
42
43static Mutex* atomicallyInitializedStaticMutex;
44
45static ThreadIdentifier mainThreadIdentifier;
46
47static Mutex& threadMapMutex()
48{
49 static Mutex mutex;
50 return mutex;
51}
52
53void initializeThreading()
54{
55 if (!g_thread_supported())
56 g_thread_init(NULL);
57 ASSERT(g_thread_supported());
58
59 if (!atomicallyInitializedStaticMutex) {
60 atomicallyInitializedStaticMutex = new Mutex;
61 threadMapMutex();
62 wtf_random_init();
63 mainThreadIdentifier = currentThread();
64 initializeMainThread();
65 }
66}
67
68void lockAtomicallyInitializedStaticMutex()
69{
70 ASSERT(atomicallyInitializedStaticMutex);
71 atomicallyInitializedStaticMutex->lock();
72}
73
74void unlockAtomicallyInitializedStaticMutex()
75{
76 atomicallyInitializedStaticMutex->unlock();
77}
78
79static HashMap<ThreadIdentifier, GThread*>& threadMap()
80{
81 static HashMap<ThreadIdentifier, GThread*> map;
82 return map;
83}
84
85static ThreadIdentifier establishIdentifierForThread(GThread*& thread)
86{
87 MutexLocker locker(threadMapMutex());
88
89 static ThreadIdentifier identifierCount = 1;
90
91 threadMap().add(identifierCount, thread);
92
93 return identifierCount++;
94}
95
96static ThreadIdentifier identifierByGthreadHandle(GThread*& thread)
97{
98 MutexLocker locker(threadMapMutex());
99
100 HashMap<ThreadIdentifier, GThread*>::iterator i = threadMap().begin();
101 for (; i != threadMap().end(); ++i) {
102 if (i->second == thread)
103 return i->first;
104 }
105
106 return 0;
107}
108
109static GThread* threadForIdentifier(ThreadIdentifier id)
110{
111 MutexLocker locker(threadMapMutex());
112
113 return threadMap().get(id);
114}
115
116static void clearThreadForIdentifier(ThreadIdentifier id)
117{
118 MutexLocker locker(threadMapMutex());
119
120 ASSERT(threadMap().contains(id));
121
122 threadMap().remove(id);
123}
124
125ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*)
126{
127 GThread* thread;
128 if (!(thread = g_thread_create(entryPoint, data, TRUE, 0))) {
129 LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
130 return 0;
131 }
132
133 ThreadIdentifier threadID = establishIdentifierForThread(thread);
134 return threadID;
135}
136
137int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
138{
139 ASSERT(threadID);
140
141 GThread* thread = threadForIdentifier(threadID);
142
143 *result = g_thread_join(thread);
144
145 clearThreadForIdentifier(threadID);
146 return 0;
147}
148
149void detachThread(ThreadIdentifier)
150{
151}
152
153ThreadIdentifier currentThread()
154{
155 GThread* currentThread = g_thread_self();
156 if (ThreadIdentifier id = identifierByGthreadHandle(currentThread))
157 return id;
158 return establishIdentifierForThread(currentThread);
159}
160
161bool isMainThread()
162{
163 return currentThread() == mainThreadIdentifier;
164}
165
166Mutex::Mutex()
167 : m_mutex(g_mutex_new())
168{
169}
170
171Mutex::~Mutex()
172{
173}
174
175void Mutex::lock()
176{
177 g_mutex_lock(m_mutex.get());
178}
179
180bool Mutex::tryLock()
181{
182 return g_mutex_trylock(m_mutex.get());
183}
184
185void Mutex::unlock()
186{
187 g_mutex_unlock(m_mutex.get());
188}
189
190ThreadCondition::ThreadCondition()
191 : m_condition(g_cond_new())
192{
193}
194
195ThreadCondition::~ThreadCondition()
196{
197}
198
199void ThreadCondition::wait(Mutex& mutex)
200{
201 g_cond_wait(m_condition.get(), mutex.impl().get());
202}
203
204bool ThreadCondition::timedWait(Mutex& mutex, double interval)
205{
206 if (interval < 0.0) {
207 wait(mutex);
208 return true;
209 }
210
211 int intervalSeconds = static_cast<int>(interval);
212 int intervalMicroseconds = static_cast<int>((interval - intervalSeconds) * 1000000.0);
213
214 GTimeVal targetTime;
215 g_get_current_time(&targetTime);
216
217 targetTime.tv_sec += intervalSeconds;
218 targetTime.tv_usec += intervalMicroseconds;
219 if (targetTime.tv_usec > 1000000) {
220 targetTime.tv_usec -= 1000000;
221 targetTime.tv_sec++;
222 }
223
224 return g_cond_timed_wait(m_condition.get(), mutex.impl().get(), &targetTime);
225}
226
227void ThreadCondition::signal()
228{
229 g_cond_signal(m_condition.get());
230}
231
232void ThreadCondition::broadcast()
233{
234 g_cond_broadcast(m_condition.get());
235}
236
237
238}
239
240#endif // !USE(PTHREADS)
Note: See TracBrowser for help on using the repository browser.