X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Flib%2Fplatform%2Fthreads%2Fmutex.h;h=2bd908e533ee00d2298c6c1083afdd6bcd44f3b5;hb=d9de2aae6b2f47b8e1faacc69adba7406b9d85f0;hp=e8481012773e428561c0e1f7c7652117926aa421;hpb=c183fa4b134719cfdba7d0a4128b4a741a8e1eb3;p=deb_libcec.git diff --git a/src/lib/platform/threads/mutex.h b/src/lib/platform/threads/mutex.h index e848101..2bd908e 100644 --- a/src/lib/platform/threads/mutex.h +++ b/src/lib/platform/threads/mutex.h @@ -2,7 +2,7 @@ /* * This file is part of the libCEC(R) library. * - * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved. + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. * libCEC(R) is an original work, containing original code. * * libCEC(R) is a trademark of Pulse-Eight Limited. @@ -31,14 +31,16 @@ * 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 "lib/platform/util/timeutils.h" + namespace PLATFORM { class PreventCopy @@ -49,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) @@ -82,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) @@ -221,39 +228,129 @@ 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) {} - inline ~CCondition(void) + CEvent(bool bAutoReset = true) : + m_bSignaled(false), + m_bBroadcast(false), + m_iWaitingThreads(0), + m_bAutoReset(bAutoReset) {} + virtual ~CEvent(void) {} + + void Broadcast(void) { + Set(true); m_condition.Broadcast(); } - inline void Broadcast(void) + void Signal(void) { - m_condition.Broadcast(); + Set(false); + m_condition.Signal(); } - inline void Signal(void) + bool Wait(void) { - m_condition.Signal(); + CLockObject lock(m_mutex); + ++m_iWaitingThreads; + + bool bReturn = m_condition.Wait(m_mutex, m_bSignaled); + return ResetAndReturn() && bReturn; } - inline bool Wait(CMutex &mutex, uint32_t iTimeout = 0) + bool Wait(uint32_t iTimeout) { - return m_condition.Wait(mutex.m_mutex, 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: - CConditionImpl m_condition; + void Set(bool bBroadcast = false) + { + CLockObject lock(m_mutex); + m_bSignaled = true; + m_bBroadcast = bBroadcast; + } + + bool ResetAndReturn(void) + { + CLockObject lock(m_mutex); + bool bReturn(m_bSignaled); + if (bReturn && (--m_iWaitingThreads == 0 || !m_bBroadcast) && m_bAutoReset) + m_bSignaled = false; + return bReturn; + } + + volatile bool m_bSignaled; + CCondition m_condition; + CMutex m_mutex; + volatile bool m_bBroadcast; + unsigned int m_iWaitingThreads; + bool m_bAutoReset; }; }