OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
3 * Copyright (C) 2009 Google Inc. All rights reserved. | 3 * Copyright (C) 2009 Google Inc. All rights reserved. |
4 * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. | 4 * Copyright (C) 2009 Torch Mobile, Inc. 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 void yield() | 257 void yield() |
258 { | 258 { |
259 ::Sleep(1); | 259 ::Sleep(1); |
260 } | 260 } |
261 | 261 |
262 ThreadIdentifier currentThread() | 262 ThreadIdentifier currentThread() |
263 { | 263 { |
264 return static_cast<ThreadIdentifier>(GetCurrentThreadId()); | 264 return static_cast<ThreadIdentifier>(GetCurrentThreadId()); |
265 } | 265 } |
266 | 266 |
267 Mutex::Mutex() | 267 MutexBase::MutexBase(bool recursive) |
268 { | 268 { |
269 m_mutex.m_recursionCount = 0; | 269 m_mutex.m_recursionCount = 0; |
270 InitializeCriticalSection(&m_mutex.m_internalMutex); | 270 InitializeCriticalSection(&m_mutex.m_internalMutex); |
271 } | 271 } |
272 | 272 |
273 Mutex::~Mutex() | 273 MutexBase::~MutexBase() |
274 { | 274 { |
275 DeleteCriticalSection(&m_mutex.m_internalMutex); | 275 DeleteCriticalSection(&m_mutex.m_internalMutex); |
276 } | 276 } |
277 | 277 |
278 void Mutex::lock() | 278 void MutexBase::lock() |
279 { | 279 { |
280 EnterCriticalSection(&m_mutex.m_internalMutex); | 280 EnterCriticalSection(&m_mutex.m_internalMutex); |
281 ++m_mutex.m_recursionCount; | 281 ++m_mutex.m_recursionCount; |
282 } | 282 } |
283 | 283 |
| 284 void MutexBase::unlock() |
| 285 { |
| 286 ASSERT(m_mutex.m_recursionCount); |
| 287 --m_mutex.m_recursionCount; |
| 288 LeaveCriticalSection(&m_mutex.m_internalMutex); |
| 289 } |
| 290 |
284 bool Mutex::tryLock() | 291 bool Mutex::tryLock() |
285 { | 292 { |
286 // This method is modeled after the behavior of pthread_mutex_trylock, | 293 // This method is modeled after the behavior of pthread_mutex_trylock, |
287 // which will return an error if the lock is already owned by the | 294 // which will return an error if the lock is already owned by the |
288 // current thread. Since the primitive Win32 'TryEnterCriticalSection' | 295 // current thread. Since the primitive Win32 'TryEnterCriticalSection' |
289 // treats this as a successful case, it changes the behavior of several | 296 // treats this as a successful case, it changes the behavior of several |
290 // tests in WebKit that check to see if the current thread already | 297 // tests in WebKit that check to see if the current thread already |
291 // owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord) | 298 // owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord) |
292 DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex); | 299 DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex); |
293 | 300 |
294 if (result != 0) { // We got the lock | 301 if (result != 0) { // We got the lock |
295 // If this thread already had the lock, we must unlock and | 302 // If this thread already had the lock, we must unlock and return |
296 // return false so that we mimic the behavior of POSIX's | 303 // false since this is a non-recursive mutex. This is to mimic the |
297 // pthread_mutex_trylock: | 304 // behavior of POSIX's pthread_mutex_trylock. We don't do this |
| 305 // check in the lock method (presumably due to performance?). This |
| 306 // means lock() will succeed even if the current thread has already |
| 307 // entered the critical section. |
298 if (m_mutex.m_recursionCount > 0) { | 308 if (m_mutex.m_recursionCount > 0) { |
299 LeaveCriticalSection(&m_mutex.m_internalMutex); | 309 LeaveCriticalSection(&m_mutex.m_internalMutex); |
300 return false; | 310 return false; |
301 } | 311 } |
302 | |
303 ++m_mutex.m_recursionCount; | 312 ++m_mutex.m_recursionCount; |
304 return true; | 313 return true; |
305 } | 314 } |
306 | 315 |
307 return false; | 316 return false; |
308 } | 317 } |
309 | 318 |
310 void Mutex::unlock() | 319 bool RecursiveMutex::tryLock() |
311 { | 320 { |
312 ASSERT(m_mutex.m_recursionCount); | 321 // CRITICAL_SECTION is recursive/reentrant so TryEnterCriticalSection will |
313 --m_mutex.m_recursionCount; | 322 // succeed if the current thread is already in the critical section. |
314 LeaveCriticalSection(&m_mutex.m_internalMutex); | 323 DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex); |
| 324 if (result == 0) { // We didn't get the lock. |
| 325 return false; |
| 326 } |
| 327 ++m_mutex.m_recursionCount; |
| 328 return true; |
315 } | 329 } |
316 | 330 |
317 bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMillisecon
ds) | 331 bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMillisecon
ds) |
318 { | 332 { |
319 // Enter the wait state. | 333 // Enter the wait state. |
320 DWORD res = WaitForSingleObject(m_blockLock, INFINITE); | 334 DWORD res = WaitForSingleObject(m_blockLock, INFINITE); |
321 ASSERT_UNUSED(res, res == WAIT_OBJECT_0); | 335 ASSERT_UNUSED(res, res == WAIT_OBJECT_0); |
322 ++m_waitersBlocked; | 336 ++m_waitersBlocked; |
323 res = ReleaseSemaphore(m_blockLock, 1, 0); | 337 res = ReleaseSemaphore(m_blockLock, 1, 0); |
324 ASSERT_UNUSED(res, res); | 338 ASSERT_UNUSED(res, res); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 } | 451 } |
438 } | 452 } |
439 | 453 |
440 ThreadCondition::~ThreadCondition() | 454 ThreadCondition::~ThreadCondition() |
441 { | 455 { |
442 CloseHandle(m_condition.m_blockLock); | 456 CloseHandle(m_condition.m_blockLock); |
443 CloseHandle(m_condition.m_blockQueue); | 457 CloseHandle(m_condition.m_blockQueue); |
444 CloseHandle(m_condition.m_unblockLock); | 458 CloseHandle(m_condition.m_unblockLock); |
445 } | 459 } |
446 | 460 |
447 void ThreadCondition::wait(Mutex& mutex) | 461 void ThreadCondition::wait(MutexBase& mutex) |
448 { | 462 { |
449 m_condition.timedWait(mutex.impl(), INFINITE); | 463 m_condition.timedWait(mutex.impl(), INFINITE); |
450 } | 464 } |
451 | 465 |
452 bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) | 466 bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime) |
453 { | 467 { |
454 DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); | 468 DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); |
455 | 469 |
456 if (!interval) { | 470 if (!interval) { |
457 // Consider the wait to have timed out, even if our condition has alread
y been signaled, to | 471 // Consider the wait to have timed out, even if our condition has alread
y been signaled, to |
458 // match the pthreads implementation. | 472 // match the pthreads implementation. |
459 return false; | 473 return false; |
460 } | 474 } |
461 | 475 |
462 return m_condition.timedWait(mutex.impl(), interval); | 476 return m_condition.timedWait(mutex.impl(), interval); |
(...skipping 20 matching lines...) Expand all Loading... |
483 // Time is too far in the future (and would overflow unsigned long) - wait f
orever. | 497 // Time is too far in the future (and would overflow unsigned long) - wait f
orever. |
484 if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) | 498 if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) |
485 return INFINITE; | 499 return INFINITE; |
486 | 500 |
487 return static_cast<DWORD>((absoluteTime - currentTime) * 1000.0); | 501 return static_cast<DWORD>((absoluteTime - currentTime) * 1000.0); |
488 } | 502 } |
489 | 503 |
490 } // namespace WTF | 504 } // namespace WTF |
491 | 505 |
492 #endif // OS(WIN) | 506 #endif // OS(WIN) |
OLD | NEW |