From 658e63c55d937f592bc76deb7fb8c7eb1f21c443 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Thu, 19 Jan 2023 20:32:36 +0000 Subject: ds: improve error handling of synchronous awaitpid EINTR needs to be retried for non-kqueue|signalfd users, and ECHILD indicates a bug in our code. --- lib/PublicInbox/DS.pm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index c849f515..523d47e4 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -30,7 +30,7 @@ use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC); use Scalar::Util qw(blessed); use PublicInbox::Syscall qw(:epoll); use PublicInbox::Tmpfile; -use Errno qw(EAGAIN EINVAL); +use Errno qw(EAGAIN EINVAL ECHILD EINTR); use Carp qw(carp croak); our @EXPORT_OK = qw(now msg_more awaitpid add_timer add_uniq_timer); @@ -703,13 +703,19 @@ sub awaitpid { $AWAIT_PIDS->{$pid} //= @cb_args ? \@cb_args : 0; # provide synchronous API if (defined(wantarray) || (!$in_loop && !@cb_args)) { - my $ret = waitpid($pid, 0) // -2; + my $ret; +again: + $ret = waitpid($pid, 0) // -2; if ($ret == $pid) { my $cb_args = delete $AWAIT_PIDS->{$pid}; @cb_args = @$cb_args if !@cb_args && $cb_args; await_cb($pid, @cb_args); - return $ret; + } else { + goto again if $! == EINTR; + carp "waitpid($pid): $!"; + delete $AWAIT_PIDS->{$pid}; } + return $ret; } # We could've just missed our SIGCHLD, cover it, here: enqueue_reap() if $in_loop; -- cgit v1.2.3-24-ge0c7