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);
}
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;