#include "../posix/os-threads.h"
#endif
+#include "../util/timeutils.h"
+
namespace PLATFORM
{
class PreventCopy
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)
}
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;
};
}
{
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;
+ };
};