]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/MboxLock.pm
No ext_urls
[public-inbox.git] / lib / PublicInbox / MboxLock.pm
index 4e2a2d9a4fed66bfb3d5328143345af51d697618..856b1e21c9f391d829c8a921d786b72b6919e635 100644 (file)
@@ -43,13 +43,13 @@ EOF
                }
                select(undef, undef, undef, $self->{delay});
        } while (now < $end);
-       croak "fcntl lock $self->{f}: $!";
+       die "fcntl lock timeout $self->{f}: $!\n";
 }
 
 sub acq_dotlock {
        my ($self) = @_;
        my $dot_lock = "$self->{f}.lock";
-       my ($pfx, $base) = ($self->{f} =~ m!(\A.*?/)([^/]+)\z!);
+       my ($pfx, $base) = ($self->{f} =~ m!(\A.*?/)?([^/]+)\z!);
        $pfx //= '';
        my $pid = $$;
        my $end = now + $self->{timeout};
@@ -60,6 +60,11 @@ sub acq_dotlock {
                        if (link($tmp, $dot_lock)) {
                                unlink($tmp) or die "unlink($tmp): $!";
                                $self->{".lock$pid"} = $dot_lock;
+                               if (substr($dot_lock, 0, 1) ne '/') {
+                                       opendir(my $dh, '.') or
+                                                       die "opendir . $!";
+                                       $self->{dh} = $dh;
+                               }
                                return;
                        }
                        unlink($tmp) or die "unlink($tmp): $!";
@@ -68,7 +73,7 @@ sub acq_dotlock {
                        croak "open $tmp (for $dot_lock): $!" if !$!{EXIST};
                }
        } while (now < $end);
-       croak "dotlock $dot_lock";
+       die "dotlock timeout $dot_lock\n";
 }
 
 sub acq_flock {
@@ -80,7 +85,7 @@ sub acq_flock {
                return if flock($self->{fh}, $op);
                select(undef, undef, undef, $self->{delay});
        } while (now < $end);
-       croak "flock $self->{f}: $!";
+       die "flock timeout $self->{f}: $!\n";
 }
 
 sub acq {
@@ -111,10 +116,19 @@ sub acq {
        $self;
 }
 
+sub _fchdir { chdir($_[0]) } # OnDestroy callback
+
 sub DESTROY {
        my ($self) = @_;
        if (my $f = $self->{".lock$$"}) {
+               my $x;
+               if (my $dh = delete $self->{dh}) {
+                       opendir my $c, '.' or die "opendir . $!";
+                       $x = PublicInbox::OnDestroy->new(\&_fchdir, $c);
+                       chdir($dh) or die "chdir (for $f): $!";
+               }
                unlink($f) or die "unlink($f): $! (lock stolen?)";
+               undef $x;
        }
 }