From: Lars Op den Kamp Date: Sat, 11 Feb 2012 01:26:37 +0000 (+0100) Subject: platform: added predicate in CCondition X-Git-Tag: upstream/2.2.0~1^2~35^2~104 X-Git-Url: https://git.piment-noir.org/?p=deb_libcec.git;a=commitdiff_plain;h=41c655b6ba019bd5c342be9fcfa8c34fad0178ef platform: added predicate in CCondition --- diff --git a/.gitignore b/.gitignore index a535243..547aa5f 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,9 @@ src/CecSharpTester/bin src/CecSharpTester/obj src/cec-config-gui/obj +src/cec-config/.deps/ +src/cec-config/cec-config +src/cec-config/*.o src/libcec-wmc/bin src/libcec-wmc/obj 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; }; } diff --git a/src/lib/platform/util/timeutils.h b/src/lib/platform/util/timeutils.h index d2992e7..367c80b 100644 --- a/src/lib/platform/util/timeutils.h +++ b/src/lib/platform/util/timeutils.h @@ -103,4 +103,20 @@ namespace PLATFORM { return (T)GetTimeMs() / (T)1000.0; } + + class CTimeout + { + public: + CTimeout(uint32_t iTime) : + m_iTarget(GetTimeMs() + iTime) {} + + uint64_t TimeLeft(void) const + { + uint64_t iNow = GetTimeMs(); + return (iNow > m_iTarget) ? 0 : m_iTarget - iNow; + } + + private: + uint64_t m_iTarget; + }; };