diff options
| author | Dan Engelbrecht <[email protected]> | 2023-11-15 11:30:56 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-15 11:30:56 +0100 |
| commit | d02b0720813a62a4f1fe875e6e784843f5c2da46 (patch) | |
| tree | 31768a0f52793b0205f156c0b827f11decc2c479 /src/zencore/thread.cpp | |
| parent | add host name to sentry (#537) (diff) | |
| download | zen-d02b0720813a62a4f1fe875e6e784843f5c2da46.tar.xz zen-d02b0720813a62a4f1fe875e6e784843f5c2da46.zip | |
fix race contdition when signaling shutdown of process and waiting for completion (#539)
Diffstat (limited to 'src/zencore/thread.cpp')
| -rw-r--r-- | src/zencore/thread.cpp | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/src/zencore/thread.cpp b/src/zencore/thread.cpp index 1f1b1b8f5..99d7cdc61 100644 --- a/src/zencore/thread.cpp +++ b/src/zencore/thread.cpp @@ -606,7 +606,7 @@ ProcessHandle::Terminate(int ExitCode) bSuccess = (WaitResult != WAIT_OBJECT_0); #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC ZEN_UNUSED(ExitCode); - bSuccess = (kill(m_Pid, SIGKILL) == 0); + bSuccess = (kill(m_Pid, SIGKILL) == 0); #endif if (!bSuccess) @@ -650,25 +650,65 @@ ProcessHandle::Wait(int TimeoutMs) break; } #elif ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + if (TimeoutMs < 0) + { + int WaitState = 0; + int Res = waitpid(m_Pid, &WaitState, WCONTINUED | WUNTRACED); + if (Res == -1) + { + int32_t LastError = zen::GetLastError(); + if (LastError == ECHILD || LastError == ESRCH) + { + return true; + } + ThrowSystemError(static_cast<uint32_t>(LastError), "Process::Wait waitpid failed"sv); + } + if (WIFEXITED(WaitState)) + { + return true; + } + if (WIFSIGNALED(WaitState)) + { + return true; + } + return false; + } + const int SleepMs = 20; timespec SleepTime = {0, SleepMs * 1000 * 1000}; - for (int i = 0;; i += SleepMs) + for (int SleepedTimeMS = 0;; SleepedTimeMS += SleepMs) { -# if ZEN_PLATFORM_MAC int WaitState = 0; - waitpid(m_Pid, &WaitState, WNOHANG | WCONTINUED | WUNTRACED); -# endif + int Res = waitpid(m_Pid, &WaitState, WNOHANG | WCONTINUED | WUNTRACED); + if (Res == -1) + { + int32_t LastError = zen::GetLastError(); + if (LastError == ECHILD || LastError == ESRCH) + { + return true; + } + ThrowSystemError(static_cast<uint32_t>(LastError), "Process::Wait waitpid failed"sv); + } + if (WIFEXITED(WaitState)) + { + return true; + } + if (WIFSIGNALED(WaitState)) + { + return true; + } if (kill(m_Pid, 0) < 0) { - if (zen::GetLastError() == ESRCH) + int32_t LastError = zen::GetLastError(); + if (LastError == ECHILD || LastError == ESRCH) { return true; } - break; + ThrowSystemError(static_cast<uint32_t>(LastError), "Process::Wait kill failed"sv); } - if (TimeoutMs >= 0 && i >= TimeoutMs) + if (SleepedTimeMS >= TimeoutMs) { return false; } |