aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/thread.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-11-16 17:24:36 +0100
committerGitHub <[email protected]>2023-11-16 17:24:36 +0100
commit85097e245029ec973182e07ef79b966e748d0efa (patch)
tree6f5bda3db6c114713a39dbf1e8e7809cf271ca32 /src/zencore/thread.cpp
parentadd zenserver state snapshot support (#543) (diff)
downloadzen-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.cpp29
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)
{