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-Status: No, score=-3.9 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 CA1391FC11 for ; Sat, 6 Feb 2021 12:18:45 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 12/17] script/lei: avoid waitpid(-1, ...) to keep tests fast Date: Sat, 6 Feb 2021 12:18:39 +0000 Message-Id: <20210206121844.10979-13-e@80x24.org> In-Reply-To: <20210206121844.10979-1-e@80x24.org> References: <20210206121844.10979-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: We only spawn one process to be reaped at the moment. tests will run the contents of script/* in the same process if possible, so any test scripts which spawn -httpd or other read-only can cause us to stall with waitpid(-1, ...) --- script/lei | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/script/lei b/script/lei index 40c21ad8..b7f21f14 100755 --- a/script/lei +++ b/script/lei @@ -14,13 +14,15 @@ my $send_cmd = PublicInbox::CmdIPC4->can('send_cmd4') // do { PublicInbox::Spawn->can('send_cmd4'); }; -sub sigchld { - my ($sig) = @_; - my $flags = $sig ? POSIX::WNOHANG() : 0; - while (waitpid(-1, $flags) > 0) {} -} +my %pids; +my $sigchld = sub { + my $flags = scalar(@_) ? POSIX::WNOHANG() : 0; + for my $pid (keys %pids) { + delete($pids{$pid}) if waitpid($pid, $flags) == $pid; + } +}; -sub exec_cmd { +my $exec_cmd = sub { my ($fds, $argc, @argv) = @_; my @old = (*STDIN{IO}, *STDOUT{IO}, *STDERR{IO}); my @rdr; @@ -29,7 +31,7 @@ sub exec_cmd { push @rdr, shift(@old), $tmpfh; } require POSIX; # WNOHANG - $SIG{CHLD} = \&sigchld; + $SIG{CHLD} = $sigchld; my $pid = fork // die "fork: $!"; if ($pid == 0) { my %env = map { split(/=/, $_, 2) } splice(@argv, $argc); @@ -38,9 +40,11 @@ sub exec_cmd { } %ENV = (%ENV, %env); exec(@argv); - die "exec: @argv: $!"; + warn "exec: @argv: $!\n"; + POSIX::_exit(1); } -} + $pids{$pid} = 1; +}; if ($send_cmd && eval { my $path = do { @@ -107,13 +111,13 @@ Falling back to (slow) one-shot mode } elsif ($buf =~ /\Achild_error ([0-9]+)\z/) { $x_it_code = $1 + 0; } elsif ($buf =~ /\Aexec (.+)\z/) { - exec_cmd(\@fds, split(/\0/, $1)); + $exec_cmd->(\@fds, split(/\0/, $1)); } else { - sigchld(); + $sigchld->(); die $buf; } } - sigchld(); + $sigchld->(); if (my $sig = ($x_it_code & 127)) { kill $sig, $$; sleep(1) while 1;