diff options
Diffstat (limited to 'src/rt/sync/lock_and_signal.cpp')
| -rw-r--r-- | src/rt/sync/lock_and_signal.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/rt/sync/lock_and_signal.cpp b/src/rt/sync/lock_and_signal.cpp index 35576f7fd97..1d0842e6c60 100644 --- a/src/rt/sync/lock_and_signal.cpp +++ b/src/rt/sync/lock_and_signal.cpp @@ -10,8 +10,15 @@ #include "lock_and_signal.h" +// FIXME: This is not a portable way of specifying an invalid pthread_t +#define INVALID_THREAD 0 + + #if defined(__WIN32__) lock_and_signal::lock_and_signal() +#if defined(DEBUG_LOCKS) + : _holding_thread(INVALID_THREAD) +#endif { _event = CreateEvent(NULL, FALSE, FALSE, NULL); @@ -30,6 +37,9 @@ lock_and_signal::lock_and_signal() #else lock_and_signal::lock_and_signal() +#if defined(DEBUG_LOCKS) + : _holding_thread(INVALID_THREAD) +#endif { CHECKED(pthread_cond_init(&_cond, NULL)); CHECKED(pthread_mutex_init(&_mutex, NULL)); @@ -47,14 +57,25 @@ lock_and_signal::~lock_and_signal() { } void lock_and_signal::lock() { + must_not_have_lock(); #if defined(__WIN32__) EnterCriticalSection(&_cs); +#if defined(DEBUG_LOCKS) + _holding_thread = GetCurrentThreadId(); +#endif #else CHECKED(pthread_mutex_lock(&_mutex)); +#if defined(DEBUG_LOCKS) + _holding_thread = pthread_self(); +#endif #endif } void lock_and_signal::unlock() { + must_have_lock(); +#if defined(DEBUG_LOCKS) + _holding_thread = INVALID_THREAD; +#endif #if defined(__WIN32__) LeaveCriticalSection(&_cs); #else @@ -66,12 +87,24 @@ void lock_and_signal::unlock() { * Wait indefinitely until condition is signaled. */ void lock_and_signal::wait() { + must_have_lock(); +#if defined(DEBUG_LOCKS) + _holding_thread = INVALID_THREAD; +#endif #if defined(__WIN32__) LeaveCriticalSection(&_cs); WaitForSingleObject(_event, INFINITE); EnterCriticalSection(&_cs); + must_not_be_locked(); +#if defined(DEBUG_LOCKS) + _holding_thread = GetCurrentThreadId(); +#endif #else CHECKED(pthread_cond_wait(&_cond, &_mutex)); + must_not_be_locked(); +#if defined(DEBUG_LOCKS) + _holding_thread = pthread_self(); +#endif #endif } @@ -86,6 +119,32 @@ void lock_and_signal::signal() { #endif } +#if defined(DEBUG_LOCKS) +bool lock_and_signal::lock_held_by_current_thread() +{ +#if defined(__WIN32__) + return _holding_thread == GetCurrentThreadId(); +#else + return pthread_equal(_holding_thread, pthread_self()); +#endif +} +#endif + +#if defined(DEBUG_LOCKS) +void lock_and_signal::must_have_lock() { + assert(lock_held_by_current_thread() && "must have lock"); +} +void lock_and_signal::must_not_have_lock() { + assert(!lock_held_by_current_thread() && "must not have lock"); +} +void lock_and_signal::must_not_be_locked() { +} +#else +void lock_and_signal::must_have_lock() { } +void lock_and_signal::must_not_have_lock() { } +void lock_and_signal::must_not_be_locked() { } +#endif + scoped_lock::scoped_lock(lock_and_signal &lock) : lock(lock) { |
