Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: Source/wtf/ThreadingWin.cpp

Issue 415083002: [oilpan]: fix deadlock when leaving a safepoint and sweeping. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: review feedback Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/wtf/ThreadingPthreads.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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)
OLDNEW
« no previous file with comments | « Source/wtf/ThreadingPthreads.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698