]> Sergey Matveev's repositories - public-inbox.git/commitdiff
script/lei: avoid waitpid(-1, ...) to keep tests fast
authorEric Wong <e@80x24.org>
Sat, 6 Feb 2021 12:18:39 +0000 (12:18 +0000)
committerEric Wong <e@80x24.org>
Sun, 7 Feb 2021 03:34:32 +0000 (03:34 +0000)
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

index 40c21ad882d0e11124a2e3dfacc4181b5a20bdbf..b7f21f1410fab4237054542cd2cdfbec72b0f8c1 100755 (executable)
@@ -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;