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