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

Last change on this file since 34424 was 31939, checked in by [email protected], 17 years ago

Reviewed by Oliver Hunt.

Initialize threadMapMutex safely (as already done in ThreadingWin).

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