summaryrefslogtreecommitdiff
path: root/Source/modules/asura-base/Threads/Conditional.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/modules/asura-base/Threads/Conditional.cpp')
-rw-r--r--Source/modules/asura-base/Threads/Conditional.cpp84
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