diff options
Diffstat (limited to 'Source/modules/asura-base/Threads/Conditional.cpp')
-rw-r--r-- | Source/modules/asura-base/Threads/Conditional.cpp | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/Source/modules/asura-base/Threads/Conditional.cpp b/Source/modules/asura-base/Threads/Conditional.cpp new file mode 100644 index 0000000..f86a81e --- /dev/null +++ b/Source/modules/asura-base/Threads/Conditional.cpp @@ -0,0 +1,84 @@ +#include "Conditional.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +Conditional::Conditional() + : m_Waiting(0) + , m_Signals(0) +{ +} + +Conditional::~Conditional() +{ +} + +void Conditional::Signal() +{ + m_Mutex.Lock(); + if (m_Waiting > m_Signals) + { + ++m_Signals; + signal(m_WaitSem); + m_Mutex.Unlock(); + wait(m_DoneSem); + } + else + { + m_Mutex.Unlock(); + } +} + +void Conditional::Broadcast() +{ + m_Mutex.Lock(); + if (m_Waiting> m_Signals) { + int i, num_waiting; + + num_waiting = (m_Waiting - m_Signals); + m_Signals = m_Waiting; + for (i = 0; i < num_waiting; ++i) { + signal(m_WaitSem); + } + m_Mutex.Unlock(); + for (i = 0; i < num_waiting; ++i) { + wait(m_DoneSem); + } + } + else { + m_Mutex.Unlock(); + } + +} + +bool Conditional::Wait(Mutex* mutex, int timeout /*= ASURA_MUTEX_MAXWAIT*/) +{ + bool retval; + + m_Mutex.Lock(); + ++m_Waiting; + m_Mutex.Unlock(); + + mutex->Unlock(); + + retval = wait(m_WaitSem, timeout); + + m_Mutex.Lock(); + if (m_Signals > 0) { + if (!retval) { + wait(m_WaitSem); + } + signal(m_DoneSem); + + --m_Signals; + } + --m_Waiting; + m_Mutex.Unlock(); + + m_Mutex.Lock(); + + return retval; +} + +namespace_end +namespace_end
\ No newline at end of file |