diff --git a/source/ps/ThreadUtil.h b/source/ps/ThreadUtil.h index a5398aef2c..76f55fdcc9 100755 --- a/source/ps/ThreadUtil.h +++ b/source/ps/ThreadUtil.h @@ -67,6 +67,25 @@ CLocker usage 2: //-------------------------------------------------------- #include "posix.h" +#include "misc.h" +#ifdef DEBUG_LOCKS + +#define LOCK_MUTEX(_mutex) STMT( \ + printf("pthread_mutex_lock: 1 %p [pid:%d]\n", _mutex, pthread_self()); \ + pthread_mutex_lock(_mutex); \ + printf("pthread_mutex_lock: 2 %p [pid:%d]\n", _mutex, pthread_self()) \ +) +#define UNLOCK_MUTEX(_mutex) STMT( \ + pthread_mutex_unlock(_mutex); \ + printf("pthread_mutex_unlock: %p [pid:%d]\n", _mutex, pthread_self()) \ +) + +#else + +#define LOCK_MUTEX(_mutex) pthread_mutex_lock(_mutex) +#define UNLOCK_MUTEX(_mutex) pthread_mutex_unlock(_mutex) + +#endif //------------------------------------------------- // Types @@ -76,6 +95,45 @@ CLocker usage 2: // Declarations //------------------------------------------------- +/** + * A Mutual Exclusion lock. + */ +class CMutex +{ +public: + inline CMutex() + { + pthread_mutex_init(&m_Mutex, NULL); + } + + inline ~CMutex() + { + if (pthread_mutex_destroy(&m_Mutex) != 0) + { + Unlock(); + pthread_mutex_destroy(&m_Mutex); + } + } + + /** + * Atomically wait for the mutex to become unlocked, then lock it. + */ + inline void Lock() + { + LOCK_MUTEX(&m_Mutex); + } + + /** + * Unlock the mutex. + */ + inline void Unlock() + { + UNLOCK_MUTEX(&m_Mutex); + } + + pthread_mutex_t m_Mutex; +}; + // CScopeLock // ---------------------------------------------------------------------| Class // Locks a CMutex over the objects lifetime @@ -84,11 +142,17 @@ class CScopeLock public: inline CScopeLock(pthread_mutex_t &mutex): m_Mutex(mutex) { - pthread_mutex_lock(&m_Mutex); + LOCK_MUTEX(&m_Mutex); } + + inline CScopeLock(CMutex &mutex): m_Mutex(mutex.m_Mutex) + { + LOCK_MUTEX(&m_Mutex); + } + inline ~CScopeLock() { - pthread_mutex_unlock(&m_Mutex); + UNLOCK_MUTEX(&m_Mutex); } private: @@ -99,10 +163,10 @@ private: // ---------------------------------------------------------------------| Class // This will not give access to the wrapped class constructors directly, // to use them you have to do CLocker(CWrappedClass(args)) - template -struct CLocker: public _T +struct CLocker: public CMutex, public _T { +public: inline CLocker() {} @@ -111,18 +175,6 @@ struct CLocker: public _T inline CLocker(_T &arg): _T(arg) {} - - inline void Lock() - { - pthread_mutex_lock(&m_Mutex); - } - - inline void Unlock() - { - pthread_mutex_unlock(&m_Mutex); - } - - pthread_mutex_t m_Mutex; }; #endif