diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp index f9d40681a60a..fa19b63385dd 100644 --- a/src/rt/sync/lock_and_signal.cpp +++ b/src/rt/sync/lock_and_signal.cpp @@ -19,7 +19,18 @@ lock_and_signal::lock_and_signal() : _holding_thread(INVALID_THREAD) { _event = CreateEvent(NULL, FALSE, FALSE, NULL); - InitializeCriticalSection(&_cs); + + // If a CRITICAL_SECTION is not initialized with a spin count, it will + // default to 0, even on multi-processor systems. MSDN suggests using + // 4000. On single-processor systems, the spin count parameter is ignored + // and the critical section's spin count defaults to 0. + const DWORD SPIN_COUNT = 4000; + CHECKED(!InitializeCriticalSectionAndSpinCount(&_cs, SPIN_COUNT)); + + // TODO? Consider checking GetProcAddress("InitializeCriticalSectionEx") + // so Windows >= Vista we can use CRITICAL_SECTION_NO_DEBUG_INFO to avoid + // allocating CRITICAL_SECTION debug info that is never released. See: + // http://stackoverflow.com/questions/804848/critical-sections-leaking-memory-on-vista-win2008#889853 } #else @@ -32,8 +43,10 @@ lock_and_signal::lock_and_signal() #endif lock_and_signal::~lock_and_signal() { + assert(_holding_thread == INVALID_THREAD); #if defined(__WIN32__) CloseHandle(_event); + DeleteCriticalSection(&_cs); #else CHECKED(pthread_cond_destroy(&_cond)); CHECKED(pthread_mutex_destroy(&_mutex)); @@ -41,6 +54,7 @@ lock_and_signal::~lock_and_signal() { } void lock_and_signal::lock() { + assert(!lock_held_by_current_thread()); #if defined(__WIN32__) EnterCriticalSection(&_cs); _holding_thread = GetCurrentThreadId(); @@ -51,6 +65,7 @@ void lock_and_signal::lock() { } void lock_and_signal::unlock() { + assert(lock_held_by_current_thread()); _holding_thread = INVALID_THREAD; #if defined(__WIN32__) LeaveCriticalSection(&_cs); @@ -69,9 +84,11 @@ void lock_and_signal::wait() { LeaveCriticalSection(&_cs); WaitForSingleObject(_event, INFINITE); EnterCriticalSection(&_cs); + assert(_holding_thread == INVALID_THREAD); _holding_thread = GetCurrentThreadId(); #else CHECKED(pthread_cond_wait(&_cond, &_mutex)); + assert(_holding_thread == INVALID_THREAD); _holding_thread = pthread_self(); #endif }