about summary refs log tree commit homepage
path: root/t
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2024-04-01 06:49:37 +0000
committerEric Wong <e@80x24.org>2024-04-03 08:28:05 +0000
commit108196adad5e70b6dd40dc431cd1033d44679483 (patch)
tree6c9f2761263a5f188ef47d58b5c652a8f7ab2497 /t
parent9aba037ad27f1ec8e9c37580d23ea7a8944e8ae5 (diff)
downloadpublic-inbox-108196adad5e70b6dd40dc431cd1033d44679483.tar.gz
getpid() isn't cached by glibc nowadays and system calls are
more expensive due to CPU vulnerability mitigations.  To
ensure we switch to the new semantics properly, introduce
a new `on_destroy' function to simplify callers.
Furthermore, most OnDestroy correctness is often tied to the
process which creates it, so make the new API default to
guarded against running in subprocesses.

For cases which require running in all children, a new
PublicInbox::OnDestroy::all call is provided.
Diffstat (limited to 't')
-rw-r--r--t/lei-sigpipe.t4
-rw-r--r--t/mbox_lock.t7
-rw-r--r--t/mh_reader.t1
-rw-r--r--t/on_destroy.t25
4 files changed, 21 insertions, 16 deletions
diff --git a/t/lei-sigpipe.t b/t/lei-sigpipe.t
index 72bc6c7d..b9fd88a6 100644
--- a/t/lei-sigpipe.t
+++ b/t/lei-sigpipe.t
@@ -26,9 +26,7 @@ SKIP: {
 # https://public-inbox.org/meta/20220227080422.gyqowrxomzu6gyin@sourcephile.fr/
 my $oldSIGPIPE = $SIG{PIPE};
 $SIG{PIPE} = 'DEFAULT';
-my $cleanup = PublicInbox::OnDestroy->new($$, sub {
-        $SIG{PIPE} = $oldSIGPIPE;
-});
+my $cleanup = on_destroy(sub { $SIG{PIPE} = $oldSIGPIPE });
 
 test_lei(sub {
         my $f = "$ENV{HOME}/big.eml";
diff --git a/t/mbox_lock.t b/t/mbox_lock.t
index c2fee0d4..1fc828aa 100644
--- a/t/mbox_lock.t
+++ b/t/mbox_lock.t
@@ -2,6 +2,7 @@
 # Copyright (C) 2021 all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
+use autodie qw(chdir);
 use POSIX qw(_exit);
 use PublicInbox::DS qw(now);
 use Errno qw(EAGAIN);
@@ -18,11 +19,11 @@ ok(!-f "$f.lock", 'no dotlock with none');
 undef $mbl;
 {
         opendir my $cur, '.' or BAIL_OUT $!;
-        my $od = PublicInbox::OnDestroy->new(sub { chdir $cur });
-        chdir $tmpdir or BAIL_OUT;
+        my $od = on_destroy \&chdir, $cur;
+        chdir $tmpdir;
         my $abs = "$tmpdir/rel.lock";
         my $rel = PublicInbox::MboxLock->acq('rel', 1, ['dotlock']);
-        chdir '/' or BAIL_OUT;
+        chdir '/';
         ok(-f $abs, 'lock with abs path created');
         undef $rel;
         ok(!-f $abs, 'lock gone despite being in the wrong dir');
diff --git a/t/mh_reader.t b/t/mh_reader.t
index c81df32e..95a7be4a 100644
--- a/t/mh_reader.t
+++ b/t/mh_reader.t
@@ -5,7 +5,6 @@ use PublicInbox::TestCommon;
 require_ok 'PublicInbox::MHreader';
 use PublicInbox::IO qw(write_file);
 use PublicInbox::Lock;
-use PublicInbox::OnDestroy;
 use PublicInbox::Eml;
 use File::Path qw(remove_tree);
 use autodie;
diff --git a/t/on_destroy.t b/t/on_destroy.t
index e7945100..e8fdf35e 100644
--- a/t/on_destroy.t
+++ b/t/on_destroy.t
@@ -1,37 +1,44 @@
 #!perl -w
 use v5.12;
 use Test::More;
-require_ok 'PublicInbox::OnDestroy';
+use PublicInbox::OnDestroy;
+use POSIX qw(_exit);
 my @x;
-my $od = PublicInbox::OnDestroy->new(sub { push @x, 'hi' });
+my $od = on_destroy sub { push @x, 'hi' };
 is_deeply(\@x, [], 'not called, yet');
 undef $od;
 is_deeply(\@x, [ 'hi' ], 'no args works');
-$od = PublicInbox::OnDestroy->new(sub { $x[0] = $_[0] }, 'bye');
+$od = on_destroy sub { $x[0] = $_[0] }, 'bye';
 is_deeply(\@x, [ 'hi' ], 'nothing changed while alive');
 undef $od;
 is_deeply(\@x, [ 'bye' ], 'arg passed');
-$od = PublicInbox::OnDestroy->new(sub { @x = @_ }, qw(x y));
+$od = on_destroy sub { @x = @_ }, qw(x y);
 undef $od;
 is_deeply(\@x, [ 'x', 'y' ], '2 args passed');
 
 open my $tmp, '+>>', undef or BAIL_OUT $!;
 $tmp->autoflush(1);
-$od = PublicInbox::OnDestroy->new(1, sub { print $tmp "$$ DESTROY\n" });
-undef $od;
+$od = on_destroy sub { print $tmp "$$ DESTROY\n" };
+my $pid = PublicInbox::OnDestroy::fork_tmp;
+if ($pid == 0) { undef $od; _exit 0; };
+waitpid($pid, 0);
+is $?, 0, 'test process exited';
 is(-s $tmp, 0, '$tmp is empty on pid mismatch');
-$od = PublicInbox::OnDestroy->new($$, sub { $tmp = $$ });
+$od->cancel;
+undef $od;
+is(-s $tmp, 0, '$tmp is empty after ->cancel');
+$od = on_destroy sub { $tmp = $$ };
 undef $od;
 is($tmp, $$, '$tmp set to $$ by callback');
 
-$od = PublicInbox::OnDestroy->new($$, sub { $tmp = 'foo' });
+$od = on_destroy sub { $tmp = 'foo' };
 $od->cancel;
 $od = undef;
 isnt($tmp, 'foo', '->cancel');
 
 if (my $nr = $ENV{TEST_LEAK_NR}) {
         for (0..$nr) {
-                $od = PublicInbox::OnDestroy->new(sub { @x = @_ }, qw(x y));
+                $od = on_destroy sub { @x = @_ }, qw(x y);
         }
 }