From 01a2a7c13c8dec894644005a221d03c262098f3a Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 17 Jan 2006 19:12:20 +0000 Subject: [PATCH] define CHECK_REENTRANT_MUTEX --- dtool/Config.pp | 4 ++++ dtool/LocalSetup.pp | 3 +++ dtool/Package.pp | 1 + panda/src/express/conditionVar.I | 8 ++++---- panda/src/express/pmutex.I | 27 +++++++++++++++++++++------ panda/src/express/pmutex.cxx | 16 +++++++++------- panda/src/express/pmutex.h | 6 ++++-- 7 files changed, 46 insertions(+), 19 deletions(-) diff --git a/dtool/Config.pp b/dtool/Config.pp index b5d6acfe16..6e45eb24a3 100644 --- a/dtool/Config.pp +++ b/dtool/Config.pp @@ -566,6 +566,10 @@ // define this true unless you have NSPR installed. #define HAVE_THREADS +// Even if threading is not defined, you might want to double-check +// that ordinary mutexes are not locked reentrantly: +#define CHECK_REENTRANT_MUTEX + // Do you want to build the network interface? What additional libraries // are required? Currently, this requires NSPR. #define NET_IPATH diff --git a/dtool/LocalSetup.pp b/dtool/LocalSetup.pp index 44072cac85..e28de4103c 100644 --- a/dtool/LocalSetup.pp +++ b/dtool/LocalSetup.pp @@ -232,6 +232,9 @@ $[cdefine HAVE_CHROMIUM] /* Define if we want to compile the threading code. */ $[cdefine HAVE_THREADS] +/* Define to check that ordinary (non-reentrant) Mutexes are not reentrantly locked. */ +$[cdefine CHECK_REENTRANT_MUTEX] + /* Define if we want to compile the net code. */ $[cdefine HAVE_NET] diff --git a/dtool/Package.pp b/dtool/Package.pp index 750ea5ff2d..f481f6d320 100644 --- a/dtool/Package.pp +++ b/dtool/Package.pp @@ -213,6 +213,7 @@ #set HAVE_OPENCV $[HAVE_OPENCV] #set HAVE_THREADS $[HAVE_THREADS] +#set CHECK_REENTRANT_MUTEX $[CHECK_REENTRANT_MUTEX] #set NET_IPATH $[unixfilename $[NET_IPATH]] #set NET_LPATH $[unixfilename $[NET_LPATH]] diff --git a/panda/src/express/conditionVar.I b/panda/src/express/conditionVar.I index 06ee6ec408..99d9795195 100644 --- a/panda/src/express/conditionVar.I +++ b/panda/src/express/conditionVar.I @@ -104,10 +104,10 @@ get_mutex() { //////////////////////////////////////////////////////////////////// INLINE void ConditionVar:: wait() { - nassertv(_mutex._locking_thread == Thread::get_current_thread()); + nassertv(_mutex.debug_is_locked()); _impl.wait(); -#ifndef NDEBUG +#ifdef CHECK_REENTRANT_MUTEX _mutex._locking_thread = Thread::get_current_thread(); #endif } @@ -130,7 +130,7 @@ wait() { //////////////////////////////////////////////////////////////////// INLINE void ConditionVar:: signal() { - nassertv(_mutex._locking_thread == Thread::get_current_thread()); + nassertv(_mutex.debug_is_locked()); _impl.signal(); } @@ -146,6 +146,6 @@ signal() { //////////////////////////////////////////////////////////////////// INLINE void ConditionVar:: signal_all() { - nassertv(_mutex._locking_thread == Thread::get_current_thread()); + nassertv(_mutex.debug_is_locked()); _impl.signal_all(); } diff --git a/panda/src/express/pmutex.I b/panda/src/express/pmutex.I index a808064dc1..4fd21beffd 100644 --- a/panda/src/express/pmutex.I +++ b/panda/src/express/pmutex.I @@ -72,8 +72,8 @@ operator = (const Mutex ©) { //////////////////////////////////////////////////////////////////// INLINE void Mutex:: lock() const { -#ifdef NDEBUG - // In the NDEBUG case, just lock the thing immediately. Don't +#ifndef CHECK_REENTRANT_MUTEX + // In the production case, just lock the thing immediately. Don't // bother with the out-of-line do_lock() method, since we won't be // performing any checks anyway. ((MutexImpl &)_impl).lock(); @@ -97,10 +97,10 @@ lock() const { //////////////////////////////////////////////////////////////////// INLINE void Mutex:: release() const { -#ifdef NDEBUG - // In the NDEBUG case, just release the thing immediately. Don't - // bother with the out-of-line do_release() method, since we won't - // be performing any checks anyway. +#ifndef CHECK_REENTRANT_MUTEX + // In the production case, just release the thing immediately. + // Don't bother with the out-of-line do_release() method, since we + // won't be performing any checks anyway. ((MutexImpl &)_impl).release(); #else @@ -109,3 +109,18 @@ release() const { ((Mutex *)this)->do_release(); #endif } + +#ifndef CHECK_REENTRANT_MUTEX +//////////////////////////////////////////////////////////////////// +// Function: Mutex::debug_is_locked +// Access: Public +// Description: Returns true if the current thread has locked the +// Mutex, false otherwise. This method is only +// meaningful if CHECK_REENTRANT_MUTEX is defined; +// otherwise, it always returns true. +//////////////////////////////////////////////////////////////////// +INLINE bool Mutex:: +debug_is_locked() const { + return true; +} +#endif // CHECK_REENTRANT_MUTEX diff --git a/panda/src/express/pmutex.cxx b/panda/src/express/pmutex.cxx index 46340d9e01..0407e7eeeb 100644 --- a/panda/src/express/pmutex.cxx +++ b/panda/src/express/pmutex.cxx @@ -19,20 +19,20 @@ #include "pmutex.h" #include "thread.h" -#ifndef NDEBUG +#ifdef CHECK_REENTRANT_MUTEX //////////////////////////////////////////////////////////////////// // Function: Mutex::debug_is_locked // Access: Public // Description: Returns true if the current thread has locked the -// Mutex, false otherwise. This method only exists in -// !NDEBUG mode, so it's only appropriate to call it -// from within an assert(). +// Mutex, false otherwise. This method is only +// meaningful if CHECK_REENTRANT_MUTEX is defined; +// otherwise, it always returns true. //////////////////////////////////////////////////////////////////// bool Mutex:: debug_is_locked() const { return (_locking_thread == Thread::get_current_thread()); } -#endif // NDEBUG +#endif // CHECK_REENTRANT_MUTEX //////////////////////////////////////////////////////////////////// // Function: Mutex::do_lock @@ -41,10 +41,12 @@ debug_is_locked() const { //////////////////////////////////////////////////////////////////// void Mutex:: do_lock() { +#ifdef CHECK_REENTRANT_MUTEX nassertv(_locking_thread != Thread::get_current_thread()); +#endif _impl.lock(); -#ifndef NDEBUG +#ifdef CHECK_REENTRANT_MUTEX _locking_thread = Thread::get_current_thread(); #endif } @@ -56,8 +58,8 @@ do_lock() { //////////////////////////////////////////////////////////////////// void Mutex:: do_release() { +#ifdef CHECK_REENTRANT_MUTEX nassertv(_locking_thread == Thread::get_current_thread()); -#ifndef NDEBUG _locking_thread = (Thread *)NULL; #endif diff --git a/panda/src/express/pmutex.h b/panda/src/express/pmutex.h index 7c33f4937f..877a60ee05 100644 --- a/panda/src/express/pmutex.h +++ b/panda/src/express/pmutex.h @@ -43,8 +43,10 @@ public: INLINE void lock() const; INLINE void release() const; -#ifndef NDEBUG +#ifdef CHECK_REENTRANT_MUTEX bool debug_is_locked() const; +#else + INLINE bool debug_is_locked() const; #endif private: @@ -54,7 +56,7 @@ private: private: MutexImpl _impl; -#ifndef NDEBUG +#ifdef CHECK_REENTRANT_MUTEX // Make sure that ordinary mutexes are not locked reentrantly // (that's what a ReMutex is for). Thread *_locking_thread;