]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/DS.pm
No ext_urls
[public-inbox.git] / lib / PublicInbox / DS.pm
index c849f515992d342c211c2329df78b7b8b604c546..0a763d0ef643ad0d5c5deb8e027b9df67d4438ae 100644 (file)
@@ -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);
 
@@ -699,20 +699,26 @@ sub long_response ($$;@) {
 }
 
 sub awaitpid {
-       my ($pid, @cb_args) = @_;
-       $AWAIT_PIDS->{$pid} //= @cb_args ? \@cb_args : 0;
+       my ($pid, @cb_args) = @_; # @cb_args = ($cb, @args), $cb may be undef
+       $AWAIT_PIDS->{$pid} = \@cb_args if @cb_args;
        # 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;
+       } elsif ($in_loop) { # We could've just missed our SIGCHLD, cover it, here:
+               enqueue_reap();
        }
-       # We could've just missed our SIGCHLD, cover it, here:
-       enqueue_reap() if $in_loop;
 }
 
 1;