diff options
| author | Martin Ridgers <[email protected]> | 2021-11-02 15:28:17 +0100 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-11-02 15:44:40 +0100 |
| commit | 0fe1efd263ef2f045c427edafc92b9ca2c2f86b0 (patch) | |
| tree | ae5b6d3e6b33de23abfe15ccac601541676d4cfa | |
| parent | Fixed shm_open() and friends link error (diff) | |
| download | zen-0fe1efd263ef2f045c427edafc92b9ca2c2f86b0.tar.xz zen-0fe1efd263ef2f045c427edafc92b9ca2c2f86b0.zip | |
Event for POSIX using std:: primitives
| -rw-r--r-- | zencore/thread.cpp | 69 |
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 +} ////////////////////////////////////////////////////////////////////////// |