108
117
static ThreadIdentifier identifierCount = 1;
110
119
threadMap().add(identifierCount, pthreadHandle);
112
121
return identifierCount++;
115
124
static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id)
117
126
MutexLocker locker(threadMapMutex());
119
128
return threadMap().get(id);
124
133
MutexLocker locker(threadMapMutex());
126
135
ASSERT(threadMap().contains(id));
128
137
threadMap().remove(id);
131
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
133
pthread_t threadHandle;
134
if (pthread_create(&threadHandle, NULL, entryPoint, data)) {
135
LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
139
return establishIdentifierForPthreadHandle(threadHandle);
140
#if PLATFORM(ANDROID)
141
// On the Android platform, threads must be registered with the VM before they run.
143
ThreadFunction entryPoint;
147
static void* runThreadWithRegistration(void* arg)
149
ThreadData* data = static_cast<ThreadData*>(arg);
150
JavaVM* vm = JSC::Bindings::getJavaVM();
153
if (vm->AttachCurrentThread(&env, 0) == JNI_OK) {
154
ret = data->entryPoint(data->arg);
155
vm->DetachCurrentThread();
161
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
163
pthread_t threadHandle;
164
ThreadData* threadData = new ThreadData();
165
threadData->entryPoint = entryPoint;
166
threadData->arg = data;
168
if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast<void*>(threadData))) {
169
LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
172
return establishIdentifierForPthreadHandle(threadHandle);
175
ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
177
pthread_t threadHandle;
178
if (pthread_create(&threadHandle, 0, entryPoint, data)) {
179
LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
183
return establishIdentifierForPthreadHandle(threadHandle);
187
void setThreadNameInternal(const char* threadName)
189
#if HAVE(PTHREAD_SETNAME_NP)
190
pthread_setname_np(threadName);
192
UNUSED_PARAM(threadName);
142
196
int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
144
198
ASSERT(threadID);
146
200
pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
148
202
int joinResult = pthread_join(pthreadHandle, result);
149
203
if (joinResult == EDEADLK)
150
204
LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
152
206
clearPthreadHandleForIdentifier(threadID);
153
207
return joinResult;
194
248
void Mutex::lock()
196
if (pthread_mutex_lock(&m_mutex) != 0)
250
int result = pthread_mutex_lock(&m_mutex);
251
ASSERT_UNUSED(result, !result);
200
254
bool Mutex::tryLock()
202
256
int result = pthread_mutex_trylock(&m_mutex);
206
else if (result == EBUSY)
263
ASSERT_NOT_REACHED();
213
267
void Mutex::unlock()
215
if (pthread_mutex_unlock(&m_mutex) != 0)
269
int result = pthread_mutex_unlock(&m_mutex);
270
ASSERT_UNUSED(result, !result);
274
ReadWriteLock::ReadWriteLock()
276
pthread_rwlock_init(&m_readWriteLock, NULL);
279
ReadWriteLock::~ReadWriteLock()
281
pthread_rwlock_destroy(&m_readWriteLock);
284
void ReadWriteLock::readLock()
286
int result = pthread_rwlock_rdlock(&m_readWriteLock);
287
ASSERT_UNUSED(result, !result);
290
bool ReadWriteLock::tryReadLock()
292
int result = pthread_rwlock_tryrdlock(&m_readWriteLock);
296
if (result == EBUSY || result == EAGAIN)
299
ASSERT_NOT_REACHED();
303
void ReadWriteLock::writeLock()
305
int result = pthread_rwlock_wrlock(&m_readWriteLock);
306
ASSERT_UNUSED(result, !result);
309
bool ReadWriteLock::tryWriteLock()
311
int result = pthread_rwlock_trywrlock(&m_readWriteLock);
315
if (result == EBUSY || result == EAGAIN)
318
ASSERT_NOT_REACHED();
322
void ReadWriteLock::unlock()
324
int result = pthread_rwlock_unlock(&m_readWriteLock);
325
ASSERT_UNUSED(result, !result);
219
328
ThreadCondition::ThreadCondition()
229
338
void ThreadCondition::wait(Mutex& mutex)
231
if (pthread_cond_wait(&m_condition, &mutex.impl()) != 0)
340
int result = pthread_cond_wait(&m_condition, &mutex.impl());
341
ASSERT_UNUSED(result, !result);
235
bool ThreadCondition::timedWait(Mutex& mutex, double secondsToWait)
344
bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
237
if (secondsToWait < 0.0) {
346
if (absoluteTime < currentTime())
349
if (absoluteTime > INT_MAX) {
242
int intervalSeconds = static_cast<int>(secondsToWait);
243
int intervalMicroseconds = static_cast<int>((secondsToWait - intervalSeconds) * 1000000.0);
245
// Current time comes in sec/microsec
247
gettimeofday(¤tTime, NULL);
249
// Target time comes in sec/nanosec
354
int timeSeconds = static_cast<int>(absoluteTime);
355
int timeNanoseconds = static_cast<int>((absoluteTime - timeSeconds) * 1E9);
250
357
timespec targetTime;
251
targetTime.tv_sec = currentTime.tv_sec + intervalSeconds;
252
targetTime.tv_nsec = (currentTime.tv_usec + intervalMicroseconds) * 1000;
253
if (targetTime.tv_nsec > 1000000000) {
254
targetTime.tv_nsec -= 1000000000;
358
targetTime.tv_sec = timeSeconds;
359
targetTime.tv_nsec = timeNanoseconds;
258
361
return pthread_cond_timedwait(&m_condition, &mutex.impl(), &targetTime) == 0;
261
364
void ThreadCondition::signal()
263
if (pthread_cond_signal(&m_condition) != 0)
366
int result = pthread_cond_signal(&m_condition);
367
ASSERT_UNUSED(result, !result);
267
370
void ThreadCondition::broadcast()
269
if (pthread_cond_broadcast(&m_condition) != 0)
372
int result = pthread_cond_broadcast(&m_condition);
373
ASSERT_UNUSED(result, !result);
273
376
} // namespace WTF
275
378
#endif // USE(PTHREADS)