platform: added predicate in CCondition
[deb_libcec.git] / src / lib / platform / threads / mutex.h
index e8481012773e428561c0e1f7c7652117926aa421..bb4e006e331b373dfacd585eb682e53e5f47f697 100644 (file)
@@ -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;
   };
 }