about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-03-25 06:20:25 +0200
committerEric Wong <e@80x24.org>2021-03-25 17:59:04 +0000
commit67379b592b29883618a380e81a3e2553702010f1 (patch)
tree0127a7baaffdb15feba6d67db44b752f0620eb66 /t
parentc1b912dea25f48958434f1e85337029b0959fc83 (diff)
downloadpublic-inbox-67379b592b29883618a380e81a3e2553702010f1.tar.gz
Perl can't check for interrupts when inside a blocking syscall,
as there's no self-pipe mechanism inside Perl itself.  So fork
a child and have it repeated kill(2) instead of relying on alarm(3).
Diffstat (limited to 't')
-rw-r--r--t/cmd_ipc.t28
1 files changed, 20 insertions, 8 deletions
diff --git a/t/cmd_ipc.t b/t/cmd_ipc.t
index 84f8fb4d..c5e715a1 100644
--- a/t/cmd_ipc.t
+++ b/t/cmd_ipc.t
@@ -10,7 +10,7 @@ pipe(my ($r, $w)) or BAIL_OUT;
 my ($send, $recv);
 require_ok 'PublicInbox::Spawn';
 my $SOCK_SEQPACKET = eval { Socket::SOCK_SEQPACKET() } // undef;
-use Time::HiRes qw(alarm);
+use Time::HiRes qw(usleep);
 
 my $do_test = sub { SKIP: {
         my ($type, $flag, $desc) = @_;
@@ -53,13 +53,25 @@ my $do_test = sub { SKIP: {
                 is_deeply(\@fds, [ undef ], "EAGAIN $desc");
                 $s2->blocking(1);
 
-                my $alrm = 0;
-                local $SIG{ALRM} = sub { $alrm++ };
-                alarm(0.001);
-                @fds = $recv->($s2, $buf, length($src) + 1);
-                ok($!{EINTR}, "EINTR set by ($desc)");
-                is_deeply(\@fds, [ undef ], "EINTR $desc");
-                is($alrm, 1, 'SIGALRM hit');
+                if ($ENV{TEST_ALRM}) {
+                        my $alrm = 0;
+                        local $SIG{ALRM} = sub { $alrm++ };
+                        my $tgt = $$;
+                        my $pid = fork // xbail "fork: $!";
+                        if ($pid == 0) {
+                                # need to loop since Perl signals are racy
+                                # (the interpreter doesn't self-pipe)
+                                while (usleep(1000)) {
+                                        kill 'ALRM', $tgt;
+                                }
+                        }
+                        @fds = $recv->($s2, $buf, length($src) + 1);
+                        ok($!{EINTR}, "EINTR set by ($desc)");
+                        kill('KILL', $pid);
+                        waitpid($pid, 0);
+                        is_deeply(\@fds, [ undef ], "EINTR $desc");
+                        ok($alrm, 'SIGALRM hit');
+                }
 
                 close $s1;
                 @fds = $recv->($s2, $buf, length($src) + 1);