Objects with DESTROY callbacks get propagated to children, so we
must be careful to not invoke waitpid from children on their
sibling processes. Only parents (and their parents...) can reap
child processes.
if ($ret == $pid) {
if ($cb) {
eval { $cb->($arg, $pid) };
if ($ret == $pid) {
if ($cb) {
eval { $cb->($arg, $pid) };
- warn "E: dwaitpid($pid) !in_loop: $@" if $@;
+ carp "E: dwaitpid($pid) !in_loop: $@" if $@;
- warn "waitpid($pid, 0) = $ret, \$!=$!, \$?=$?";
+ carp "waitpid($pid, 0) = $ret, \$!=$!, \$?=$?";
# sock => writable pipe to Gcf2::loop
# in => pipe we read from
# pid => PID of Gcf2::loop process
# sock => writable pipe to Gcf2::loop
# in => pipe we read from
# pid => PID of Gcf2::loop process
+# owner_pid => process which spawned {pid}
sub new {
my ($rdr) = @_;
my $self = bless {}, __PACKAGE__;
sub new {
my ($rdr) = @_;
my $self = bless {}, __PACKAGE__;
$rdr //= {};
$rdr->{0} = $out_r;
my $cmd = [$^X, qw[-MPublicInbox::Gcf2 -e PublicInbox::Gcf2::loop()]];
$rdr //= {};
$rdr->{0} = $out_r;
my $cmd = [$^X, qw[-MPublicInbox::Gcf2 -e PublicInbox::Gcf2::loop()]];
+ $self->{owner_pid} = $$;
@$self{qw(in pid)} = popen_rd($cmd, $env, $rdr);
fcntl($out_w, 1031, 4096) if $^O eq 'linux'; # 1031: F_SETPIPE_SZ
$out_w->autoflush(1);
@$self{qw(in pid)} = popen_rd($cmd, $env, $rdr);
fcntl($out_w, 1031, 4096) if $^O eq 'linux'; # 1031: F_SETPIPE_SZ
$out_w->autoflush(1);
delete $self->{in};
# GitAsyncCat::event_step may reap us with WNOHANG, too
my $pid = delete $self->{pid} or return;
delete $self->{in};
# GitAsyncCat::event_step may reap us with WNOHANG, too
my $pid = delete $self->{pid} or return;
- PublicInbox::DS->in_loop ? $self->close : delete($self->{sock});
- dwaitpid $pid;
+ if ($$ == $self->{owner_pid}) {
+ PublicInbox::DS->in_loop ? $self->close : delete($self->{sock});
+ dwaitpid $pid;
+ }
}
my ($in_r, $p) = popen_rd(\@cmd, undef, $redir);
$self->{$pid} = $p;
}
my ($in_r, $p) = popen_rd(\@cmd, undef, $redir);
$self->{$pid} = $p;
+ $self->{"$pid.owner"} = $$;
$out_w->autoflush(1);
if ($^O eq 'linux') { # 1031: F_SETPIPE_SZ
fcntl($out_w, 1031, 4096);
$out_w->autoflush(1);
if ($^O eq 'linux') { # 1031: F_SETPIPE_SZ
fcntl($out_w, 1031, 4096);
# GitAsyncCat::event_step may delete {pid}
my $p = delete $self->{$pid} or return;
# GitAsyncCat::event_step may delete {pid}
my $p = delete $self->{$pid} or return;
+ dwaitpid($p) if $$ == $self->{"$pid.owner"};
}
sub cat_async_abort ($) {
}
sub cat_async_abort ($) {