about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-01-19 20:32:36 +0000
committerEric Wong <e@80x24.org>2023-01-19 20:54:23 +0000
commit658e63c55d937f592bc76deb7fb8c7eb1f21c443 (patch)
tree459d4305886086479836faaf200ed7da4bc78534
parent876ee62a686c66037427232541c0ca4ebebfff94 (diff)
downloadpublic-inbox-658e63c55d937f592bc76deb7fb8c7eb1f21c443.tar.gz
EINTR needs to be retried for non-kqueue|signalfd users,
and ECHILD indicates a bug in our code.
-rw-r--r--lib/PublicInbox/DS.pm12
1 files 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;