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

Last change on this file since 31730 was 31690, checked in by Adam Roben, 17 years ago

Add WTF::isMainThread

Reviewed by Alexey Proskuryakov.

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