X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fplatform%2Fthreads%2Fmutex.h;h=286cc3274dd6240e73acba22886188a64553063d;hb=90b7066f7129c01c5bd012a00677ebdc0c42ae89;hp=bb4e006e331b373dfacd585eb682e53e5f47f697;hpb=41c655b6ba019bd5c342be9fcfa8c34fad0178ef;p=deb_libcec.git diff --git a/src/lib/platform/threads/mutex.h b/src/lib/platform/threads/mutex.h index bb4e006..286cc32 100644 --- a/src/lib/platform/threads/mutex.h +++ b/src/lib/platform/threads/mutex.h @@ -31,15 +31,15 @@ * http://www.pulse-eight.net/ */ -#include "../os.h" +#include "lib/platform/os.h" #if defined(__WINDOWS__) -#include "../windows/os-threads.h" +#include "lib/platform/windows/os-threads.h" #else -#include "../posix/os-threads.h" +#include "lib/platform/posix/os-threads.h" #endif -#include "../util/timeutils.h" +#include "lib/platform/util/timeutils.h" namespace PLATFORM { @@ -51,14 +51,16 @@ namespace PLATFORM private: inline PreventCopy(const PreventCopy &c) { *this = c; } - inline PreventCopy &operator=(const PreventCopy &c){ *this = c; return *this; } + inline PreventCopy &operator=(const PreventCopy & UNUSED(c)){ return *this; } }; - class CCondition; + template + class CCondition; class CMutex : public PreventCopy { - friend class CCondition; + template + friend class CCondition; public: inline CMutex(void) : m_iLockCount(0) @@ -84,9 +86,12 @@ namespace PLATFORM inline bool Lock(void) { - MutexLock(m_mutex); - ++m_iLockCount; - return true; + if (MutexLock(m_mutex)) + { + ++m_iLockCount; + return true; + } + return false; } inline void Unlock(void) @@ -223,16 +228,68 @@ namespace PLATFORM volatile bool m_bIsLocked; }; - class CCondition : public PreventCopy + template + class CCondition : public PreventCopy + { + public: + inline CCondition(void) {} + inline ~CCondition(void) + { + m_condition.Broadcast(); + } + + inline void Broadcast(void) + { + m_condition.Broadcast(); + } + + inline void Signal(void) + { + m_condition.Signal(); + } + + inline bool Wait(CMutex &mutex, _Predicate &predicate) + { + while(!predicate) + m_condition.Wait(mutex.m_mutex); + return true; + } + + inline bool Wait(CMutex &mutex, _Predicate &predicate, uint32_t iTimeout) + { + if (iTimeout == 0) + return Wait(mutex, predicate); + + if (predicate) + return true; + + bool bReturn(false); + bool bBreak(false); + CTimeout timeout(iTimeout); + uint32_t iMsLeft(0); + + while (!bReturn && !bBreak) + { + iMsLeft = timeout.TimeLeft(); + if ((bReturn = predicate) == false && (bBreak = iMsLeft == 0) == false) + m_condition.Wait(mutex.m_mutex, iMsLeft); + } + return bReturn; + } + + private: + CConditionImpl m_condition; + }; + + class CEvent { public: - inline CCondition(void) : - m_bPredicate(false), - m_iWaitingThreads(0) {} - inline ~CCondition(void) - { - Broadcast(); - } + CEvent(bool bAutoReset = true) : + m_bSignaled(false), + m_bBroadcast(false), + m_iWaitingThreads(0), + m_bAutoReset(bAutoReset) {} + virtual ~CEvent(void) {} void Broadcast(void) { @@ -246,57 +303,54 @@ namespace PLATFORM m_condition.Signal(); } - bool Wait(CMutex &mutex, uint32_t iTimeout = 0) + bool Wait(void) { - { - CLockObject lock(m_mutex); - ++m_iWaitingThreads; - } + 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); - } + bool bReturn = m_condition.Wait(m_mutex, m_bSignaled); + return ResetAndReturn() && bReturn; + } - return ResetAndReturn(); + bool Wait(uint32_t iTimeout) + { + if (iTimeout == 0) + return Wait(); + + CLockObject lock(m_mutex); + ++m_iWaitingThreads; + bool bReturn = m_condition.Wait(m_mutex, m_bSignaled, iTimeout); + return ResetAndReturn() && bReturn; } static void Sleep(uint32_t iTimeout) { - CCondition w; - CMutex m; - CLockObject lock(m); - w.Wait(m, iTimeout); + CEvent event; + event.Wait(iTimeout); } private: void Set(bool bBroadcast = false) { CLockObject lock(m_mutex); - m_bPredicate = true; + m_bSignaled = 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; + bool bReturn(m_bSignaled); + if (bReturn && (--m_iWaitingThreads == 0 || !m_bBroadcast) && m_bAutoReset) + m_bSignaled = false; return bReturn; } - CMutex m_mutex; - CConditionImpl m_condition; - volatile bool m_bPredicate; - volatile bool m_bBroadcast; - unsigned int m_iWaitingThreads; + volatile bool m_bSignaled; + CCondition m_condition; + CMutex m_mutex; + volatile bool m_bBroadcast; + unsigned int m_iWaitingThreads; + bool m_bAutoReset; }; }