diff options
author | Eric Wong <e@80x24.org> | 2023-11-26 02:11:04 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2023-11-26 19:34:57 +0000 |
commit | 51b2fa7fb2b7b1caed8b1dde4613992a192225ed (patch) | |
tree | 2ca5f2161edc525a895223837e4455d4d9ed7646 /lib/PublicInbox/IO.pm | |
parent | e7f0919b6ec2e959444efb12af44658aa1ea9fb4 (diff) | |
download | public-inbox-51b2fa7fb2b7b1caed8b1dde4613992a192225ed.tar.gz |
While the {inflight} array should be tied to the IO object even more tightly, that's not an easy task with our current code. So take some small steps by introducing a gcf_inflight helper to validate the ownership of the process and to drain the inflight array via the awaitpid callback. This hopefully fix problems with t/lei-q-save.t (still) hanging occasionally on v2 outputs since git->cleanup/->DESTROY was getting called in v2 shard workers.
Diffstat (limited to 'lib/PublicInbox/IO.pm')
-rw-r--r-- | lib/PublicInbox/IO.pm | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/lib/PublicInbox/IO.pm b/lib/PublicInbox/IO.pm index fcebac59..6593dcdf 100644 --- a/lib/PublicInbox/IO.pm +++ b/lib/PublicInbox/IO.pm @@ -15,8 +15,10 @@ use Errno qw(EINTR EAGAIN); sub waitcb { # awaitpid callback my ($pid, $errref, $cb, @args) = @_; + $errref //= \my $workaround_await_pids_clobbered; $$errref = $?; # sets .cerr for _close - $cb->($pid, @args) if $cb; + $cb->($pid, @args) if $cb; # may clobber $? + $? = $$errref; } sub attach_pid { @@ -33,6 +35,11 @@ sub attached_pid { ${${*$io}{pi_io_reap} // []}[1]; } +sub owner_pid { + my ($io) = @_; + ${${*$io}{pi_io_reap} // [-1]}[0]; +} + # caller cares about error result if they call close explicitly # reap->[2] may be set before this is called via waitcb sub close { @@ -40,8 +47,12 @@ sub close { my $ret = $io->SUPER::close; my $reap = delete ${*$io}{pi_io_reap}; return $ret unless $reap && $reap->[0] == $$; - ${$reap->[2]} // (my $w = awaitpid($reap->[1])); # sets [2] - ($? = ${$reap->[2]}) ? '' : $ret; + if (defined ${$reap->[2]}) { # reap_pids already reaped asynchronously + $? = ${$reap->[2]}; + } else { # wait synchronously + my $w = awaitpid($reap->[1]); + } + $? ? '' : $ret; # use $?, AWAIT_PIDS may be cleared on ->Reset (FIXME?) } sub DESTROY { |