From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 5A9AD1FD57 for ; Sun, 12 Jan 2020 21:17:58 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 08/11] ds: rely on autovivication for waitpid bits Date: Sun, 12 Jan 2020 21:17:53 +0000 Message-Id: <20200112211756.23100-9-e@yhbt.net> In-Reply-To: <20200112211756.23100-1-e@yhbt.net> References: <20200112211756.23100-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: No need to create an arrayref until we need it, and fix up a comment while we're in the area. Some aesthetic changes while we're at it: - Rename $WaitPids to $wait_pids to make it clear this is unique to our implementation and not in Danga::Socket. - rewrite dwaitpid() to reduce indentation level --- lib/PublicInbox/DS.pm | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index ac9065f2..a78037f6 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -39,7 +39,7 @@ 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 $wait_pids; # list of [ pid, callback, callback_arg ] my $later_queue; # callbacks my $EXPMAP; # fd -> [ idle_time, $self ] our $EXPTIME = 180; # 3 minutes @@ -71,7 +71,7 @@ Reset all state =cut sub Reset { %DescriptorMap = (); - $WaitPids = []; + $wait_pids = undef; $later_queue = []; $EXPMAP = {}; $nextq = $ToClose = $reap_timer = $later_timer = $exp_timer = undef; @@ -226,25 +226,23 @@ 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) @@ -626,15 +624,11 @@ 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 () {