Commit 4c2796b0 authored by Oliver Giles's avatar Oliver Giles

Ignore ECHILD in UnixEventPort::ChildSet::checkExits

If no child process has changed state, waitpid() returns zero. But if there
are no more child processes at all, it returns -1 and sets errno to ECHILD.
Since checkExits calls waitpid() in a loop, it must ignore ECHILD.

+Unit test modified to exhibit the unexpected behaviour.
parent 00cd0c38
......@@ -707,12 +707,7 @@ TEST(AsyncUnixTest, ChildProcess) {
KJ_DEFER(KJ_SYSCALL(sigprocmask(SIG_SETMASK, &oldsigs, nullptr)) { break; });
TestChild child1(port, 123);
TestChild child2(port, 234);
TestChild child3(port, 345);
KJ_EXPECT(!child1.promise.poll(waitScope));
KJ_EXPECT(!child2.promise.poll(waitScope));
KJ_EXPECT(!child3.promise.poll(waitScope));
child1.kill(SIGTERM);
......@@ -722,6 +717,9 @@ TEST(AsyncUnixTest, ChildProcess) {
KJ_EXPECT(WEXITSTATUS(status) == 123);
}
TestChild child2(port, 234);
TestChild child3(port, 345);
KJ_EXPECT(!child2.promise.poll(waitScope));
KJ_EXPECT(!child3.promise.poll(waitScope));
......
......@@ -145,7 +145,12 @@ void UnixEventPort::ChildSet::checkExits() {
for (;;) {
int status;
pid_t pid;
KJ_SYSCALL(pid = waitpid(-1, &status, WNOHANG));
KJ_SYSCALL_HANDLE_ERRORS(pid = waitpid(-1, &status, WNOHANG)) {
case ECHILD:
return;
default:
KJ_FAIL_SYSCALL("waitpid()", error);
}
if (pid == 0) break;
auto iter = waiters.find(pid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment