X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FDS.pm;h=673c24eb86a81315eccd8b41457385d51072aba1;hb=3874e93d923a3f23816cf307c257120c6941cad2;hp=f7c8ad2ba085d2b1654b596e6e4393e5cf40460e;hpb=a65ebdc3a1f064bab0cddf64b34caad49f1c4c9c;p=public-inbox.git diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index f7c8ad2b..673c24eb 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -39,8 +39,8 @@ use Errno qw(EAGAIN EINVAL); use Carp qw(confess carp); my $nextq; # queue for next_tick -my $WaitPids; # list of [ pid, callback, callback_arg ] -my $later_queue; # callbacks +my $wait_pids; # list of [ pid, callback, callback_arg ] +my $later_queue; # list of callbacks to run at some later interval my $EXPMAP; # fd -> [ idle_time, $self ] our $EXPTIME = 180; # 3 minutes my ($later_timer, $reap_timer, $exp_timer); @@ -71,11 +71,9 @@ Reset all state =cut sub Reset { %DescriptorMap = (); - $nextq = []; - $WaitPids = []; - $later_queue = []; + $wait_pids = $later_queue = undef; $EXPMAP = {}; - $ToClose = $reap_timer = $later_timer = $exp_timer = undef; + $nextq = $ToClose = $reap_timer = $later_timer = $exp_timer = undef; $LoopTimeout = -1; # no timeout by default @Timers = (); @@ -179,8 +177,8 @@ sub FirstTimeEventLoop { sub now () { clock_gettime(CLOCK_MONOTONIC) } sub next_tick () { - my $q = $nextq; - $nextq = []; + my $q = $nextq or return; + $nextq = undef; for (@$q) { # we avoid "ref" on blessed refs to workaround a Perl 5.16.3 leak: # https://rt.perl.org/Public/Bug/Display.html?id=114340 @@ -196,7 +194,7 @@ sub next_tick () { sub RunTimers { next_tick(); - return ((@$nextq || $ToClose) ? 0 : $LoopTimeout) unless @Timers; + return (($nextq || $ToClose) ? 0 : $LoopTimeout) unless @Timers; my $now = now(); @@ -207,7 +205,7 @@ sub RunTimers { } # timers may enqueue into nextq: - return 0 if (@$nextq || $ToClose); + return 0 if ($nextq || $ToClose); return $LoopTimeout unless @Timers; @@ -227,29 +225,27 @@ sub RunTimers { } # We can't use waitpid(-1) safely here since it can hit ``, system(), -# and other things. So we scan the $WaitPids list, which is hopefully -# not too big. +# and other things. So we scan the $wait_pids list, which is hopefully +# not too big. We keep $wait_pids small by not calling dwaitpid() +# until we've hit EOF when reading the stdout of the child. sub reap_pids { - my $tmp = $WaitPids; - $WaitPids = []; - $reap_timer = undef; + my $tmp = $wait_pids or return; + $wait_pids = $reap_timer = undef; foreach my $ary (@$tmp) { my ($pid, $cb, $arg) = @$ary; my $ret = waitpid($pid, WNOHANG); if ($ret == 0) { - push @$WaitPids, $ary; + push @$wait_pids, $ary; # autovivifies @$wait_pids } 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); - } + # we may not be done, yet, and could've missed/masked a SIGCHLD: + $reap_timer = add_timer(1, \&reap_pids) if $wait_pids; } # reentrant SIGCHLD handler (since reap_pids is not reentrant) -sub enqueue_reap ($) { push @$nextq, \&reap_pids }; +sub enqueue_reap ($) { push @$nextq, \&reap_pids }; # autovivifies sub in_loop () { $in_loop } @@ -353,7 +349,7 @@ sub new { ### I N S T A N C E M E T H O D S ##################################################################### -sub requeue ($) { push @$nextq, $_[0] } +sub requeue ($) { push @$nextq, $_[0] } # autovivifies =head2 C<< $obj->close >> @@ -627,28 +623,22 @@ sub shutdn ($) { # must be called with eval, PublicInbox::DS may not be loaded (see t/qspawn.t) sub dwaitpid ($$$) { - my ($pid, $cb, $arg) = @_; - if ($in_loop) { - push @$WaitPids, [ $pid, $cb, $arg ]; + die "Not in EventLoop\n" unless $in_loop; + push @$wait_pids, [ @_ ]; # [ $pid, $cb, $arg ] - # We could've just missed our SIGCHLD, cover it, here: - requeue(\&reap_pids); - } else { - die "Not in EventLoop\n"; - } + # We could've just missed our SIGCHLD, cover it, here: + requeue(\&reap_pids); } sub _run_later () { - my $run = $later_queue; - $later_timer = undef; - $later_queue = []; - $_->() for @$run; + my $run = $later_queue or return; + $later_timer = $later_queue = undef; + $_->() for @$run; } sub later ($) { - my ($cb) = @_; - push @$later_queue, $cb; - $later_timer //= add_timer(60, \&_run_later); + push @$later_queue, $_[0]; # autovivifies @$later_queue + $later_timer //= add_timer(60, \&_run_later); } sub expire_old () {