X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fplatform%2Fthreads%2Fmutex.h;h=bb4e006e331b373dfacd585eb682e53e5f47f697;hb=41c655b6ba019bd5c342be9fcfa8c34fad0178ef;hp=e8481012773e428561c0e1f7c7652117926aa421;hpb=39b1216c4883c7a3a351283e61e58891699ef091;p=deb_libcec.git diff --git a/src/lib/platform/threads/mutex.h b/src/lib/platform/threads/mutex.h index e848101..bb4e006 100644 --- a/src/lib/platform/threads/mutex.h +++ b/src/lib/platform/threads/mutex.h @@ -39,6 +39,8 @@ #include "../posix/os-threads.h" #endif +#include "../util/timeutils.h" + namespace PLATFORM { class PreventCopy @@ -224,25 +226,46 @@ namespace PLATFORM class CCondition : public PreventCopy { public: - inline CCondition(void) {} + inline CCondition(void) : + m_bPredicate(false), + m_iWaitingThreads(0) {} inline ~CCondition(void) { - m_condition.Broadcast(); + Broadcast(); } - inline void Broadcast(void) + void Broadcast(void) { + Set(true); m_condition.Broadcast(); } - inline void Signal(void) + void Signal(void) { + Set(false); m_condition.Signal(); } - inline bool Wait(CMutex &mutex, uint32_t iTimeout = 0) + bool Wait(CMutex &mutex, uint32_t iTimeout = 0) { - return m_condition.Wait(mutex.m_mutex, iTimeout); + { + CLockObject lock(m_mutex); + ++m_iWaitingThreads; + } + + if (iTimeout > 0) + { + CTimeout timeout(iTimeout); + while (!m_bPredicate && timeout.TimeLeft() > 0) + m_condition.Wait(mutex.m_mutex, timeout.TimeLeft()); + } + else + { + while (!m_bPredicate) + m_condition.Wait(mutex.m_mutex, 0); + } + + return ResetAndReturn(); } static void Sleep(uint32_t iTimeout) @@ -254,6 +277,26 @@ namespace PLATFORM } private: + void Set(bool bBroadcast = false) + { + CLockObject lock(m_mutex); + m_bPredicate = true; + m_bBroadcast = bBroadcast; + } + + bool ResetAndReturn(void) + { + CLockObject lock(m_mutex); + bool bReturn(m_bPredicate); + if (bReturn && (--m_iWaitingThreads == 0 || !m_bBroadcast)) + m_bPredicate = false; + return bReturn; + } + + CMutex m_mutex; CConditionImpl m_condition; + volatile bool m_bPredicate; + volatile bool m_bBroadcast; + unsigned int m_iWaitingThreads; }; }