diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-03-30 18:37:30 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-03-31 19:51:29 -0700 |
| commit | c8dc6fcb4cd29e5fb6c509149871b869b951295d (patch) | |
| tree | 3556f9f57afa10a2f14c4ff44042b6db174ded2a /src/rt/sync | |
| parent | 609144f7a6adba552602feb7e50e7c4d6a815fae (diff) | |
| download | rust-c8dc6fcb4cd29e5fb6c509149871b869b951295d.tar.gz rust-c8dc6fcb4cd29e5fb6c509149871b869b951295d.zip | |
Revert "rt: Remove lock_held_by_current_thread"
Adds back the ability to make assertions about locks, but only under the --enable-debug configuration This reverts commit b247de64583e2ab527088813ba9192824554e801. Conflicts: src/rt/rust_sched_loop.cpp
Diffstat (limited to 'src/rt/sync')
| -rw-r--r-- | src/rt/sync/lock_and_signal.cpp | 59 | ||||
| -rw-r--r-- | src/rt/sync/lock_and_signal.h | 19 |
2 files changed, 78 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) { diff --git a/src/rt/sync/lock_and_signal.h b/src/rt/sync/lock_and_signal.h index f4ffcc30a68..fae9b1c24ea 100644 --- a/src/rt/sync/lock_and_signal.h +++ b/src/rt/sync/lock_and_signal.h @@ -2,15 +2,31 @@ #ifndef LOCK_AND_SIGNAL_H #define LOCK_AND_SIGNAL_H +#ifndef RUST_NDEBUG +#define DEBUG_LOCKS +#endif + class lock_and_signal { #if defined(__WIN32__) HANDLE _event; CRITICAL_SECTION _cs; +#if defined(DEBUG_LOCKS) + DWORD _holding_thread; +#endif #else pthread_cond_t _cond; pthread_mutex_t _mutex; +#if defined(DEBUG_LOCKS) + pthread_t _holding_thread; +#endif #endif +#if defined(DEBUG_LOCKS) + bool lock_held_by_current_thread(); +#endif + + void must_not_be_locked(); + public: lock_and_signal(); virtual ~lock_and_signal(); @@ -19,6 +35,9 @@ public: void unlock(); void wait(); void signal(); + + void must_have_lock(); + void must_not_have_lock(); }; class scoped_lock { |
