aboutsummaryrefslogtreecommitdiff
path: root/zencore/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zencore/thread.cpp')
-rw-r--r--zencore/thread.cpp69
1 files changed, 64 insertions, 5 deletions
diff --git a/zencore/thread.cpp b/zencore/thread.cpp
index 572627c4d..ff86ff5fc 100644
--- a/zencore/thread.cpp
+++ b/zencore/thread.cpp
@@ -9,6 +9,10 @@
#if ZEN_PLATFORM_WINDOWS
# include <zencore/windows.h>
#elif ZEN_PLATFORM_LINUX
+# include <chrono>
+# include <condition_variable>
+# include <mutex>
+
# include <pthread.h>
# include <unistd.h>
#endif
@@ -102,40 +106,80 @@ RwLock::ReleaseExclusive()
//////////////////////////////////////////////////////////////////////////
-#if ZEN_PLATFORM_WINDOWS
+#if !ZEN_PLATFORM_WINDOWS
+struct EventInner
+{
+ std::mutex Mutex;
+ std::condition_variable CondVar;
+ bool volatile bSet = false;
+};
+#endif // !ZEN_PLATFORM_WINDOWS
Event::Event()
{
- m_EventHandle = CreateEvent(nullptr, true, false, nullptr);
+ bool bManualReset = true;
+ bool bInitialState = false;
+
+#if ZEN_PLATFORM_WINDOWS
+ m_EventHandle = CreateEvent(nullptr, bManualReset, bInitialState, nullptr);
+#else
+ ZEN_UNUSED(bManualReset);
+ auto* Inner = new EventInner();
+ Inner->bSet = bInitialState;
+ m_EventHandle = Inner;
+#endif
}
Event::~Event()
{
- CloseHandle(m_EventHandle);
+ Close();
}
void
Event::Set()
{
+#if ZEN_PLATFORM_WINDOWS
SetEvent(m_EventHandle);
+#else
+ auto* Inner = (EventInner*)m_EventHandle;
+ {
+ std::unique_lock Lock(Inner->Mutex);
+ Inner->bSet = true;
+ }
+ Inner->CondVar.notify_all();
+#endif
}
void
Event::Reset()
{
+#if ZEN_PLATFORM_WINDOWS
ResetEvent(m_EventHandle);
+#else
+ auto* Inner = (EventInner*)m_EventHandle;
+ {
+ std::unique_lock Lock(Inner->Mutex);
+ Inner->bSet = false;
+ }
+#endif
}
void
Event::Close()
{
+#if ZEN_PLATFORM_WINDOWS
CloseHandle(m_EventHandle);
+#else
+ auto* Inner = (EventInner*)m_EventHandle;
+ delete Inner;
+#endif
m_EventHandle = nullptr;
}
bool
Event::Wait(int TimeoutMs)
{
+#if ZEN_PLATFORM_WINDOWS
using namespace std::literals;
const DWORD Timeout = (TimeoutMs < 0) ? INFINITE : TimeoutMs;
@@ -148,9 +192,24 @@ Event::Wait(int TimeoutMs)
}
return (Result == WAIT_OBJECT_0);
-}
+#else
+ auto* Inner = (EventInner*)m_EventHandle;
-#endif // ZEN_PLATFORM_WINDOWS
+ if (TimeoutMs >= 0)
+ {
+ std::unique_lock Lock(Inner->Mutex);
+ return Inner->CondVar.wait_for(
+ Lock,
+ std::chrono::milliseconds(TimeoutMs),
+ [&] { return Inner->bSet; }
+ );
+ }
+
+ std::unique_lock Lock(Inner->Mutex);
+ Inner->CondVar.wait(Lock, [&] { return Inner->bSet; });
+ return true;
+#endif
+}
//////////////////////////////////////////////////////////////////////////