Merge pull request #1869 from cpeterso/master
rt: lock_and_signal fixes
This commit is contained in:
commit
657ef8ef60
1 changed files with 18 additions and 1 deletions
|
@ -19,7 +19,18 @@ lock_and_signal::lock_and_signal()
|
||||||
: _holding_thread(INVALID_THREAD)
|
: _holding_thread(INVALID_THREAD)
|
||||||
{
|
{
|
||||||
_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
_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
|
#else
|
||||||
|
@ -32,8 +43,10 @@ lock_and_signal::lock_and_signal()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
lock_and_signal::~lock_and_signal() {
|
lock_and_signal::~lock_and_signal() {
|
||||||
|
assert(_holding_thread == INVALID_THREAD);
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
CloseHandle(_event);
|
CloseHandle(_event);
|
||||||
|
DeleteCriticalSection(&_cs);
|
||||||
#else
|
#else
|
||||||
CHECKED(pthread_cond_destroy(&_cond));
|
CHECKED(pthread_cond_destroy(&_cond));
|
||||||
CHECKED(pthread_mutex_destroy(&_mutex));
|
CHECKED(pthread_mutex_destroy(&_mutex));
|
||||||
|
@ -41,6 +54,7 @@ lock_and_signal::~lock_and_signal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void lock_and_signal::lock() {
|
void lock_and_signal::lock() {
|
||||||
|
assert(!lock_held_by_current_thread());
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
EnterCriticalSection(&_cs);
|
EnterCriticalSection(&_cs);
|
||||||
_holding_thread = GetCurrentThreadId();
|
_holding_thread = GetCurrentThreadId();
|
||||||
|
@ -51,6 +65,7 @@ void lock_and_signal::lock() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void lock_and_signal::unlock() {
|
void lock_and_signal::unlock() {
|
||||||
|
assert(lock_held_by_current_thread());
|
||||||
_holding_thread = INVALID_THREAD;
|
_holding_thread = INVALID_THREAD;
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
LeaveCriticalSection(&_cs);
|
LeaveCriticalSection(&_cs);
|
||||||
|
@ -69,9 +84,11 @@ void lock_and_signal::wait() {
|
||||||
LeaveCriticalSection(&_cs);
|
LeaveCriticalSection(&_cs);
|
||||||
WaitForSingleObject(_event, INFINITE);
|
WaitForSingleObject(_event, INFINITE);
|
||||||
EnterCriticalSection(&_cs);
|
EnterCriticalSection(&_cs);
|
||||||
|
assert(_holding_thread == INVALID_THREAD);
|
||||||
_holding_thread = GetCurrentThreadId();
|
_holding_thread = GetCurrentThreadId();
|
||||||
#else
|
#else
|
||||||
CHECKED(pthread_cond_wait(&_cond, &_mutex));
|
CHECKED(pthread_cond_wait(&_cond, &_mutex));
|
||||||
|
assert(_holding_thread == INVALID_THREAD);
|
||||||
_holding_thread = pthread_self();
|
_holding_thread = pthread_self();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue