| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) | 3 * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) |
| 4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. | 4 * Copyright (C) 2011 Research In Motion Limited. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * | 9 * |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 #endif | 57 #endif |
| 58 | 58 |
| 59 #if OS(LINUX) || OS(ANDROID) | 59 #if OS(LINUX) || OS(ANDROID) |
| 60 #include <unistd.h> | 60 #include <unistd.h> |
| 61 #endif | 61 #endif |
| 62 | 62 |
| 63 namespace WTF { | 63 namespace WTF { |
| 64 | 64 |
| 65 static Mutex* atomicallyInitializedStaticMutex; | 65 static Mutex* atomicallyInitializedStaticMutex; |
| 66 | 66 |
| 67 void initializeThreading() | 67 void initializeThreading() { |
| 68 { | 68 // This should only be called once. |
| 69 // This should only be called once. | 69 ASSERT(!atomicallyInitializedStaticMutex); |
| 70 ASSERT(!atomicallyInitializedStaticMutex); | |
| 71 | 70 |
| 72 // StringImpl::empty() does not construct its static string in a threadsafe
fashion, | 71 // StringImpl::empty() does not construct its static string in a threadsafe fa
shion, |
| 73 // so ensure it has been initialized from here. | 72 // so ensure it has been initialized from here. |
| 74 StringImpl::empty(); | 73 StringImpl::empty(); |
| 75 StringImpl::empty16Bit(); | 74 StringImpl::empty16Bit(); |
| 76 atomicallyInitializedStaticMutex = new Mutex; | 75 atomicallyInitializedStaticMutex = new Mutex; |
| 77 wtfThreadData(); | 76 wtfThreadData(); |
| 78 s_dtoaP5Mutex = new Mutex; | 77 s_dtoaP5Mutex = new Mutex; |
| 79 initializeDates(); | 78 initializeDates(); |
| 80 // Force initialization of static DoubleToStringConverter converter variable | 79 // Force initialization of static DoubleToStringConverter converter variable |
| 81 // inside EcmaScriptConverter function while we are in single thread mode. | 80 // inside EcmaScriptConverter function while we are in single thread mode. |
| 82 double_conversion::DoubleToStringConverter::EcmaScriptConverter(); | 81 double_conversion::DoubleToStringConverter::EcmaScriptConverter(); |
| 83 } | 82 } |
| 84 | 83 |
| 85 void lockAtomicallyInitializedStaticMutex() | 84 void lockAtomicallyInitializedStaticMutex() { |
| 86 { | 85 ASSERT(atomicallyInitializedStaticMutex); |
| 87 ASSERT(atomicallyInitializedStaticMutex); | 86 atomicallyInitializedStaticMutex->lock(); |
| 88 atomicallyInitializedStaticMutex->lock(); | |
| 89 } | 87 } |
| 90 | 88 |
| 91 void unlockAtomicallyInitializedStaticMutex() | 89 void unlockAtomicallyInitializedStaticMutex() { |
| 92 { | 90 atomicallyInitializedStaticMutex->unlock(); |
| 93 atomicallyInitializedStaticMutex->unlock(); | |
| 94 } | 91 } |
| 95 | 92 |
| 96 ThreadIdentifier currentThread() | 93 ThreadIdentifier currentThread() { |
| 97 { | |
| 98 #if OS(MACOSX) | 94 #if OS(MACOSX) |
| 99 return pthread_mach_thread_np(pthread_self()); | 95 return pthread_mach_thread_np(pthread_self()); |
| 100 #elif OS(LINUX) | 96 #elif OS(LINUX) |
| 101 return syscall(__NR_gettid); | 97 return syscall(__NR_gettid); |
| 102 #elif OS(ANDROID) | 98 #elif OS(ANDROID) |
| 103 return gettid(); | 99 return gettid(); |
| 104 #else | 100 #else |
| 105 return reinterpret_cast<uintptr_t>(pthread_self()); | 101 return reinterpret_cast<uintptr_t>(pthread_self()); |
| 106 #endif | 102 #endif |
| 107 } | 103 } |
| 108 | 104 |
| 109 MutexBase::MutexBase(bool recursive) | 105 MutexBase::MutexBase(bool recursive) { |
| 110 { | 106 pthread_mutexattr_t attr; |
| 111 pthread_mutexattr_t attr; | 107 pthread_mutexattr_init(&attr); |
| 112 pthread_mutexattr_init(&attr); | 108 pthread_mutexattr_settype(&attr, recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD
_MUTEX_NORMAL); |
| 113 pthread_mutexattr_settype(&attr, recursive ? PTHREAD_MUTEX_RECURSIVE : PTHRE
AD_MUTEX_NORMAL); | |
| 114 | 109 |
| 115 int result = pthread_mutex_init(&m_mutex.m_internalMutex, &attr); | 110 int result = pthread_mutex_init(&m_mutex.m_internalMutex, &attr); |
| 116 ASSERT_UNUSED(result, !result); | 111 ASSERT_UNUSED(result, !result); |
| 117 #if ENABLE(ASSERT) | 112 #if ENABLE(ASSERT) |
| 118 m_mutex.m_recursionCount = 0; | 113 m_mutex.m_recursionCount = 0; |
| 119 #endif | 114 #endif |
| 120 | 115 |
| 121 pthread_mutexattr_destroy(&attr); | 116 pthread_mutexattr_destroy(&attr); |
| 122 } | 117 } |
| 123 | 118 |
| 124 MutexBase::~MutexBase() | 119 MutexBase::~MutexBase() { |
| 125 { | 120 int result = pthread_mutex_destroy(&m_mutex.m_internalMutex); |
| 126 int result = pthread_mutex_destroy(&m_mutex.m_internalMutex); | 121 ASSERT_UNUSED(result, !result); |
| 127 ASSERT_UNUSED(result, !result); | |
| 128 } | 122 } |
| 129 | 123 |
| 130 void MutexBase::lock() | 124 void MutexBase::lock() { |
| 131 { | 125 int result = pthread_mutex_lock(&m_mutex.m_internalMutex); |
| 132 int result = pthread_mutex_lock(&m_mutex.m_internalMutex); | 126 ASSERT_UNUSED(result, !result); |
| 133 ASSERT_UNUSED(result, !result); | |
| 134 #if ENABLE(ASSERT) | 127 #if ENABLE(ASSERT) |
| 135 ++m_mutex.m_recursionCount; | 128 ++m_mutex.m_recursionCount; |
| 136 #endif | 129 #endif |
| 137 } | 130 } |
| 138 | 131 |
| 139 void MutexBase::unlock() | 132 void MutexBase::unlock() { |
| 140 { | |
| 141 #if ENABLE(ASSERT) | 133 #if ENABLE(ASSERT) |
| 142 ASSERT(m_mutex.m_recursionCount); | 134 ASSERT(m_mutex.m_recursionCount); |
| 143 --m_mutex.m_recursionCount; | 135 --m_mutex.m_recursionCount; |
| 144 #endif | 136 #endif |
| 145 int result = pthread_mutex_unlock(&m_mutex.m_internalMutex); | 137 int result = pthread_mutex_unlock(&m_mutex.m_internalMutex); |
| 146 ASSERT_UNUSED(result, !result); | 138 ASSERT_UNUSED(result, !result); |
| 147 } | 139 } |
| 148 | 140 |
| 149 // There is a separate tryLock implementation for the Mutex and the | 141 // There is a separate tryLock implementation for the Mutex and the |
| 150 // RecursiveMutex since on Windows we need to manually check if tryLock should | 142 // RecursiveMutex since on Windows we need to manually check if tryLock should |
| 151 // succeed or not for the non-recursive mutex. On Linux the two implementations | 143 // succeed or not for the non-recursive mutex. On Linux the two implementations |
| 152 // are equal except we can assert the recursion count is always zero for the | 144 // are equal except we can assert the recursion count is always zero for the |
| 153 // non-recursive mutex. | 145 // non-recursive mutex. |
| 154 bool Mutex::tryLock() | 146 bool Mutex::tryLock() { |
| 155 { | 147 int result = pthread_mutex_trylock(&m_mutex.m_internalMutex); |
| 156 int result = pthread_mutex_trylock(&m_mutex.m_internalMutex); | 148 if (result == 0) { |
| 157 if (result == 0) { | |
| 158 #if ENABLE(ASSERT) | 149 #if ENABLE(ASSERT) |
| 159 // The Mutex class is not recursive, so the recursionCount should be | 150 // The Mutex class is not recursive, so the recursionCount should be |
| 160 // zero after getting the lock. | 151 // zero after getting the lock. |
| 161 ASSERT(!m_mutex.m_recursionCount); | 152 ASSERT(!m_mutex.m_recursionCount); |
| 162 ++m_mutex.m_recursionCount; | 153 ++m_mutex.m_recursionCount; |
| 163 #endif | 154 #endif |
| 164 return true; | 155 return true; |
| 165 } | 156 } |
| 166 if (result == EBUSY) | 157 if (result == EBUSY) |
| 167 return false; | 158 return false; |
| 168 | 159 |
| 169 ASSERT_NOT_REACHED(); | 160 ASSERT_NOT_REACHED(); |
| 170 return false; | 161 return false; |
| 171 } | 162 } |
| 172 | 163 |
| 173 bool RecursiveMutex::tryLock() | 164 bool RecursiveMutex::tryLock() { |
| 174 { | 165 int result = pthread_mutex_trylock(&m_mutex.m_internalMutex); |
| 175 int result = pthread_mutex_trylock(&m_mutex.m_internalMutex); | 166 if (result == 0) { |
| 176 if (result == 0) { | |
| 177 #if ENABLE(ASSERT) | 167 #if ENABLE(ASSERT) |
| 178 ++m_mutex.m_recursionCount; | 168 ++m_mutex.m_recursionCount; |
| 179 #endif | 169 #endif |
| 180 return true; | 170 return true; |
| 181 } | 171 } |
| 182 if (result == EBUSY) | 172 if (result == EBUSY) |
| 183 return false; | 173 return false; |
| 184 | 174 |
| 185 ASSERT_NOT_REACHED(); | 175 ASSERT_NOT_REACHED(); |
| 186 return false; | 176 return false; |
| 187 } | 177 } |
| 188 | 178 |
| 189 ThreadCondition::ThreadCondition() | 179 ThreadCondition::ThreadCondition() { |
| 190 { | 180 pthread_cond_init(&m_condition, nullptr); |
| 191 pthread_cond_init(&m_condition, nullptr); | |
| 192 } | 181 } |
| 193 | 182 |
| 194 ThreadCondition::~ThreadCondition() | 183 ThreadCondition::~ThreadCondition() { |
| 195 { | 184 pthread_cond_destroy(&m_condition); |
| 196 pthread_cond_destroy(&m_condition); | |
| 197 } | 185 } |
| 198 | 186 |
| 199 void ThreadCondition::wait(MutexBase& mutex) | 187 void ThreadCondition::wait(MutexBase& mutex) { |
| 200 { | 188 PlatformMutex& platformMutex = mutex.impl(); |
| 201 PlatformMutex& platformMutex = mutex.impl(); | 189 int result = pthread_cond_wait(&m_condition, &platformMutex.m_internalMutex); |
| 202 int result = pthread_cond_wait(&m_condition, &platformMutex.m_internalMutex)
; | 190 ASSERT_UNUSED(result, !result); |
| 203 ASSERT_UNUSED(result, !result); | |
| 204 #if ENABLE(ASSERT) | 191 #if ENABLE(ASSERT) |
| 205 ++platformMutex.m_recursionCount; | 192 ++platformMutex.m_recursionCount; |
| 206 #endif | 193 #endif |
| 207 } | 194 } |
| 208 | 195 |
| 209 bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime) | 196 bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime) { |
| 210 { | 197 if (absoluteTime < currentTime()) |
| 211 if (absoluteTime < currentTime()) | 198 return false; |
| 212 return false; | |
| 213 | 199 |
| 214 if (absoluteTime > INT_MAX) { | 200 if (absoluteTime > INT_MAX) { |
| 215 wait(mutex); | 201 wait(mutex); |
| 216 return true; | 202 return true; |
| 217 } | 203 } |
| 218 | 204 |
| 219 int timeSeconds = static_cast<int>(absoluteTime); | 205 int timeSeconds = static_cast<int>(absoluteTime); |
| 220 int timeNanoseconds = static_cast<int>((absoluteTime - timeSeconds) * 1E9); | 206 int timeNanoseconds = static_cast<int>((absoluteTime - timeSeconds) * 1E9); |
| 221 | 207 |
| 222 timespec targetTime; | 208 timespec targetTime; |
| 223 targetTime.tv_sec = timeSeconds; | 209 targetTime.tv_sec = timeSeconds; |
| 224 targetTime.tv_nsec = timeNanoseconds; | 210 targetTime.tv_nsec = timeNanoseconds; |
| 225 | 211 |
| 226 PlatformMutex& platformMutex = mutex.impl(); | 212 PlatformMutex& platformMutex = mutex.impl(); |
| 227 int result = pthread_cond_timedwait(&m_condition, &platformMutex.m_internalM
utex, &targetTime); | 213 int result = pthread_cond_timedwait(&m_condition, &platformMutex.m_internalMut
ex, &targetTime); |
| 228 #if ENABLE(ASSERT) | 214 #if ENABLE(ASSERT) |
| 229 ++platformMutex.m_recursionCount; | 215 ++platformMutex.m_recursionCount; |
| 230 #endif | 216 #endif |
| 231 return result == 0; | 217 return result == 0; |
| 232 } | 218 } |
| 233 | 219 |
| 234 void ThreadCondition::signal() | 220 void ThreadCondition::signal() { |
| 235 { | 221 int result = pthread_cond_signal(&m_condition); |
| 236 int result = pthread_cond_signal(&m_condition); | 222 ASSERT_UNUSED(result, !result); |
| 237 ASSERT_UNUSED(result, !result); | |
| 238 } | 223 } |
| 239 | 224 |
| 240 void ThreadCondition::broadcast() | 225 void ThreadCondition::broadcast() { |
| 241 { | 226 int result = pthread_cond_broadcast(&m_condition); |
| 242 int result = pthread_cond_broadcast(&m_condition); | 227 ASSERT_UNUSED(result, !result); |
| 243 ASSERT_UNUSED(result, !result); | |
| 244 } | 228 } |
| 245 | 229 |
| 246 #if ENABLE(ASSERT) | 230 #if ENABLE(ASSERT) |
| 247 static bool s_threadCreated = false; | 231 static bool s_threadCreated = false; |
| 248 | 232 |
| 249 bool isAtomicallyInitializedStaticMutexLockHeld() | 233 bool isAtomicallyInitializedStaticMutexLockHeld() { |
| 250 { | 234 return atomicallyInitializedStaticMutex && atomicallyInitializedStaticMutex->l
ocked(); |
| 251 return atomicallyInitializedStaticMutex && atomicallyInitializedStaticMutex-
>locked(); | |
| 252 } | 235 } |
| 253 | 236 |
| 254 bool isBeforeThreadCreated() | 237 bool isBeforeThreadCreated() { |
| 255 { | 238 return !s_threadCreated; |
| 256 return !s_threadCreated; | |
| 257 } | 239 } |
| 258 | 240 |
| 259 void willCreateThread() | 241 void willCreateThread() { |
| 260 { | 242 s_threadCreated = true; |
| 261 s_threadCreated = true; | |
| 262 } | 243 } |
| 263 #endif | 244 #endif |
| 264 | 245 |
| 265 } // namespace WTF | 246 } // namespace WTF |
| 266 | 247 |
| 267 #endif // OS(POSIX) | 248 #endif // OS(POSIX) |
| OLD | NEW |