- my $tmp = $WaitPids;
- $WaitPids = [];
- $reap_timer = undef;
- foreach my $ary (@$tmp) {
- my ($pid, $cb, $arg) = @$ary;
- my $ret = waitpid($pid, WNOHANG);
- if ($ret == 0) {
- push @$WaitPids, $ary;
- } elsif ($cb) {
- eval { $cb->($arg, $pid) };
- }
- }
- if (@$WaitPids) {
- # we may not be donea, and we may miss our
- $reap_timer = add_timer(1, \&reap_pids);
- }
+ $reap_armed = undef;
+ my $tmp = $wait_pids or return;
+ $wait_pids = undef;
+ foreach my $ary (@$tmp) {
+ my ($pid, $cb, $arg) = @$ary;
+ my $ret = waitpid($pid, WNOHANG);
+ if ($ret == 0) {
+ push @$wait_pids, $ary; # autovivifies @$wait_pids
+ } elsif ($cb) {
+ eval { $cb->($arg, $pid) };
+ }
+ }
+ # we may not be done, yet, and could've missed/masked a SIGCHLD:
+ if ($wait_pids && !$reap_armed) {
+ $reap_timer //= add_timer(1, \&reap_pids_timed);
+ }
+}
+
+sub reap_pids_timed {
+ $reap_timer = undef;
+ goto \&reap_pids;