diff options
| author | Martin Ridgers <[email protected]> | 2021-11-11 12:53:05 +0100 |
|---|---|---|
| committer | Martin Ridgers <[email protected]> | 2021-11-11 13:14:23 +0100 |
| commit | d312856e0cb89be73f16e328858eb5ab04aeec02 (patch) | |
| tree | 5275db2837c224f0f06762c64bcb77d43395def6 | |
| parent | Check if an event is already set before waiting on it (diff) | |
| download | zen-d312856e0cb89be73f16e328858eb5ab04aeec02.tar.xz zen-d312856e0cb89be73f16e328858eb5ab04aeec02.zip | |
NamedEvent is no longer an Event-type object.
Platforms other than Windows do not really have a named event-like
primitive or ones that are close are fallible if a process
hard-terminates. Separating from Event more clearly conveys the use of
NamedEvent objects; to synchronise two processes.
| -rw-r--r-- | zencore/include/zencore/thread.h | 31 | ||||
| -rw-r--r-- | zencore/thread.cpp | 41 | ||||
| -rw-r--r-- | zenutil/include/zenutil/zenserverprocess.h | 4 |
3 files changed, 69 insertions, 7 deletions
diff --git a/zencore/include/zencore/thread.h b/zencore/include/zencore/thread.h index 3feb12936..2fe7cc63e 100644 --- a/zencore/include/zencore/thread.h +++ b/zencore/include/zencore/thread.h @@ -102,11 +102,36 @@ protected: /** Basic abstraction of an IPC mechanism (aka 'binary semaphore') */ -class NamedEvent : public Event +class NamedEvent { public: - ZENCORE_API explicit NamedEvent(std::string_view EventName); - ZENCORE_API explicit NamedEvent(std::u8string_view EventName); + NamedEvent() = default; + ZENCORE_API explicit NamedEvent(std::string_view EventName); + ZENCORE_API explicit NamedEvent(std::u8string_view EventName); + ZENCORE_API ~NamedEvent(); + ZENCORE_API void Close(); + ZENCORE_API void Set(); + ZENCORE_API bool Wait(int TimeoutMs=-1); + + NamedEvent(NamedEvent&& Rhs) noexcept + : m_EventHandle(Rhs.m_EventHandle) + { + Rhs.m_EventHandle = nullptr; + } + + inline NamedEvent& operator = (NamedEvent&& Rhs) noexcept + { + std::swap(m_EventHandle, Rhs.m_EventHandle); + return *this; + } + + +protected: + void* m_EventHandle = nullptr; + +private: + NamedEvent(const NamedEvent& Rhs) = delete; + NamedEvent& operator = (const NamedEvent& Rhs) = delete; }; /** Basic abstraction of a named (system wide) mutex primitive diff --git a/zencore/thread.cpp b/zencore/thread.cpp index 3e40b6336..6c5419494 100644 --- a/zencore/thread.cpp +++ b/zencore/thread.cpp @@ -228,7 +228,7 @@ Event::Wait(int TimeoutMs) #if ZEN_PLATFORM_WINDOWS -NamedEvent::NamedEvent(std::u8string_view EventName) : Event(nullptr) +NamedEvent::NamedEvent(std::u8string_view EventName) { using namespace std::literals; @@ -239,7 +239,7 @@ NamedEvent::NamedEvent(std::u8string_view EventName) : Event(nullptr) m_EventHandle = CreateEventA(nullptr, true, false, Name.c_str()); } -NamedEvent::NamedEvent(std::string_view EventName) : Event(nullptr) +NamedEvent::NamedEvent(std::string_view EventName) { using namespace std::literals; @@ -250,6 +250,43 @@ NamedEvent::NamedEvent(std::string_view EventName) : Event(nullptr) m_EventHandle = CreateEventA(nullptr, true, false, Name.c_str()); } +NamedEvent::~NamedEvent() +{ + Close(); +} + +void NamedEvent::Close() +{ + if (m_EventHandle == nullptr) + { + return; + } + + CloseHandle(m_EventHandle); + + m_EventHandle = nullptr; +} + +void NamedEvent::Set() +{ + SetEvent(m_EventHandle); +} + +bool NamedEvent::Wait(int TimeoutMs) +{ + const DWORD Timeout = (TimeoutMs < 0) ? INFINITE : TimeoutMs; + + DWORD Result = WaitForSingleObject(m_EventHandle, Timeout); + + if (Result == WAIT_FAILED) + { + using namespace std::literals; + zen::ThrowLastError("Event wait failed"sv); + } + + return (Result == WAIT_OBJECT_0); +} + #endif // ZEN_PLATFORM_WINDOWS ////////////////////////////////////////////////////////////////////////// diff --git a/zenutil/include/zenutil/zenserverprocess.h b/zenutil/include/zenutil/zenserverprocess.h index 8a4f9604d..55b9a50cd 100644 --- a/zenutil/include/zenutil/zenserverprocess.h +++ b/zenutil/include/zenutil/zenserverprocess.h @@ -67,8 +67,8 @@ struct ZenServerInstance private: ZenServerEnvironment& m_Env; ProcessHandle m_Process; - Event m_ReadyEvent; - Event m_ShutdownEvent; + NamedEvent m_ReadyEvent; + NamedEvent m_ShutdownEvent; bool m_Terminate = false; std::filesystem::path m_TestDir; bool m_MeshEnabled = false; |