diff options
| author | Stefan Boberg <[email protected]> | 2023-11-16 17:24:36 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-16 17:24:36 +0100 |
| commit | 85097e245029ec973182e07ef79b966e748d0efa (patch) | |
| tree | 6f5bda3db6c114713a39dbf1e8e7809cf271ca32 /src/zencore/thread.cpp | |
| parent | add zenserver state snapshot support (#543) (diff) | |
| download | zen-85097e245029ec973182e07ef79b966e748d0efa.tar.xz zen-85097e245029ec973182e07ef79b966e748d0efa.zip | |
further posix event improvements (#549)
* changed posix event implementation to use std::atomic instead of volatile
* ensure Event::Close() can take lock before deleting the inner object
* don't try to take the Event lock if the event is already signaled
* changed logic around Event::Wait without time-out. this works around some apparent issues on MacOS/Linux
* fix logic for posix process exit wait
Diffstat (limited to 'src/zencore/thread.cpp')
| -rw-r--r-- | src/zencore/thread.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/zencore/thread.cpp b/src/zencore/thread.cpp index 27a5ec1ae..1174f902f 100644 --- a/src/zencore/thread.cpp +++ b/src/zencore/thread.cpp @@ -190,7 +190,7 @@ Event::Set() auto* Inner = (EventInner*)m_EventHandle; { std::unique_lock Lock(Inner->Mutex); - Inner->bSet = true; + Inner->bSet.store(true); } Inner->CondVar.notify_all(); #endif @@ -205,7 +205,7 @@ Event::Reset() auto* Inner = (EventInner*)m_EventHandle; { std::unique_lock Lock(Inner->Mutex); - Inner->bSet = false; + Inner->bSet.store(false); } #endif } @@ -217,6 +217,10 @@ Event::Close() CloseHandle(m_EventHandle); #else auto* Inner = (EventInner*)m_EventHandle; + { + std::unique_lock Lock(Inner->Mutex); + Inner->bSet.store(true); + } delete Inner; #endif m_EventHandle = nullptr; @@ -239,13 +243,18 @@ Event::Wait(int TimeoutMs) return (Result == WAIT_OBJECT_0); #else - auto* Inner = (EventInner*)m_EventHandle; + auto* Inner = reinterpret_cast<EventInner*>(m_EventHandle); + + if (Inner->bSet.load()) + { + return true; + } if (TimeoutMs >= 0) { std::unique_lock Lock(Inner->Mutex); - if (Inner->bSet) + if (Inner->bSet.load()) { return true; } @@ -253,11 +262,15 @@ Event::Wait(int TimeoutMs) return Inner->CondVar.wait_for(Lock, std::chrono::milliseconds(TimeoutMs), [&] { return Inner->bSet.load(); }); } + // Infinite wait. This does not actually call the wait() function to work around + // an apparent issue in the underlying implementation. + std::unique_lock Lock(Inner->Mutex); - if (!Inner->bSet) + if (!Inner->bSet.load()) { - Inner->CondVar.wait(Lock, [&] { return Inner->bSet.load(); }); + while (!Inner->CondVar.wait_for(Lock, std::chrono::milliseconds(1000), [&] { return Inner->bSet.load(); })) + ; } return true; @@ -656,6 +669,9 @@ ProcessHandle::Wait(int TimeoutMs) { int WaitState = 0; int Res = waitpid(m_Pid, &WaitState, WNOHANG | WCONTINUED | WUNTRACED); +# if 1 + ZEN_UNUSED(Res); +# else if (Res == -1) { int32_t LastError = zen::GetLastError(); @@ -665,6 +681,7 @@ ProcessHandle::Wait(int TimeoutMs) } ThrowSystemError(static_cast<uint32_t>(LastError), "Process::Wait waitpid failed"sv); } +# endif if (kill(m_Pid, 0) < 0) { |