]> Sergey Matveev's repositories - public-inbox.git/commitdiff
on_destroy: support PID owner guard
authorEric Wong <e@80x24.org>
Thu, 31 Dec 2020 13:51:54 +0000 (13:51 +0000)
committerEric Wong <e@80x24.org>
Fri, 1 Jan 2021 05:00:40 +0000 (05:00 +0000)
Since we'll be forking for Xapian indexing and maybe
other places, having a simple guard in place to ensure
OnDestroy doesn't unexpectedly unlink files or similar
is a safer option.

lib/PublicInbox/LEI.pm
lib/PublicInbox/Lock.pm
lib/PublicInbox/OnDestroy.pm
script/public-inbox-init
t/on_destroy.t

index b84e24ef953da9800823278b678c46ca38e1f6fa..4af85d49bbb83a3b9b483fbab7f4b680771d3953 100644 (file)
@@ -745,9 +745,8 @@ sub lazy_start {
        # reading the <$daemon> pipe.
        openlog($path, 'pid', 'user');
        local $SIG{__WARN__} = sub { syslog('warning', "@_") };
-       my $owner_pid = $$;
-       my $on_destroy = PublicInbox::OnDestroy->new(sub {
-               syslog('crit', "$@") if $@ && $$ == $owner_pid;
+       my $on_destroy = PublicInbox::OnDestroy->new($$, sub {
+               syslog('crit', "$@") if $@;
        });
        open STDERR, '>&STDIN' or die "redirect stderr failed: $!";
        open STDOUT, '>&STDIN' or die "redirect stdout failed: $!";
index f6eaa5ce1101128eef02885f444e09b08f5fcbb1..1d0b4f9cbcbb104741bb6cb09396184d71fcad53 100644 (file)
@@ -36,9 +36,9 @@ sub lock_release {
 
 # caller must use return value
 sub lock_for_scope {
-       my ($self) = @_;
+       my ($self, @single_pid) = @_;
        $self->lock_acquire;
-       PublicInbox::OnDestroy->new(\&lock_release, $self);
+       PublicInbox::OnDestroy->new(@single_pid, \&lock_release, $self);
 }
 
 sub new_tmp {
index 841f87d45eabe27ea676536f64268a88127a4953..65ebd7dcf574f5aa72243add2b0df55f355d794a 100644 (file)
@@ -10,6 +10,11 @@ sub new {
 
 sub DESTROY {
        my ($cb, @args) = @{$_[0]};
+       if (!ref($cb)) {
+               my $pid = $cb;
+               return if $pid != $$;
+               $cb = shift @args;
+       }
        $cb->(@args) if $cb;
 }
 
index 693f5ca17ced941ac936ba4e43895fc739628d2e..222d0c603f6b1e93384b1ab369a99552ba8aa630 100755 (executable)
@@ -92,7 +92,7 @@ sysopen($lockfh, $lockfile, O_RDWR|O_CREAT|O_EXCL) or do {
        exit(255);
 };
 require PublicInbox::OnDestroy;
-my $auto_unlink = PublicInbox::OnDestroy->new(sub { unlink $lockfile });
+my $auto_unlink = PublicInbox::OnDestroy->new($$, sub { unlink $lockfile });
 my ($perm, %seen);
 if (-e $pi_config) {
        open(my $oh, '<', $pi_config) or die "unable to read $pi_config: $!\n";
index 8b85b48ecb7b361ff2b056d53f3e45a197f6c4ee..0de67d0bcde10c116e49270dd20a7dff3b1ea72e 100644 (file)
@@ -16,6 +16,15 @@ $od = PublicInbox::OnDestroy->new(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;
+is(-s $tmp, 0, '$tmp is empty on pid mismatch');
+$od = PublicInbox::OnDestroy->new($$, sub { $tmp = $$ });
+undef $od;
+is($tmp, $$, '$tmp set to $$ by callback');
+
 if (my $nr = $ENV{TEST_LEAK_NR}) {
        for (0..$nr) {
                $od = PublicInbox::OnDestroy->new(sub { @x = @_ }, qw(x y));