about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-11-30 11:41:00 +0000
committerEric Wong <e@80x24.org>2023-11-30 21:36:55 +0000
commitce30f3933fcb31cb0e7b6ac0956c1c8e64fedba3 (patch)
tree82fc38c5c888dd14a96055647836a4881dd10368 /lib/PublicInbox
parentf49f741ad77f0829492fe0b019255079a05f1f88 (diff)
downloadpublic-inbox-ce30f3933fcb31cb0e7b6ac0956c1c8e64fedba3.tar.gz
It saves some code in case we keep libgit2 around.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/Gcf2.pm16
-rw-r--r--lib/PublicInbox/Git.pm27
2 files changed, 18 insertions, 25 deletions
diff --git a/lib/PublicInbox/Gcf2.pm b/lib/PublicInbox/Gcf2.pm
index dcbb201d..78392990 100644
--- a/lib/PublicInbox/Gcf2.pm
+++ b/lib/PublicInbox/Gcf2.pm
@@ -9,7 +9,7 @@ use PublicInbox::Spawn qw(which run_qx); # may set PERL_INLINE_DIRECTORY
 use Fcntl qw(SEEK_SET);
 use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
 use IO::Handle; # autoflush
-use PublicInbox::Git;
+use PublicInbox::Git qw($ck_unlinked_packs);
 use PublicInbox::Lock;
 use autodie qw(close open seek truncate);
 
@@ -86,16 +86,6 @@ sub add_alt ($$) {
         1;
 }
 
-sub have_unlinked_files () {
-        # FIXME: port gcf2-like over to git.git so we won't need to
-        # deal with libgit2
-        return 1 if $^O ne 'linux';
-        if (my $s = PublicInbox::IO::try_cat("/proc/$$/maps")) {
-                return 1 if /\.(?:idx|pack) \(deleted\)/s;
-        }
-        undef;
-}
-
 # Usage: $^X -MPublicInbox::Gcf2 -e PublicInbox::Gcf2::loop [EXPIRE-TIMEOUT]
 # (see lib/PublicInbox/Gcf2Client.pm)
 sub loop (;$) {
@@ -104,6 +94,7 @@ sub loop (;$) {
         my (%seen, $check_at);
         STDERR->autoflush(1);
         STDOUT->autoflush(1);
+        my $pid = $$;
 
         while (<STDIN>) {
                 chomp;
@@ -130,7 +121,8 @@ sub loop (;$) {
                         $check_at //= $now + $exp;
                         if ($now > $check_at) {
                                 undef $check_at;
-                                if (have_unlinked_files()) {
+                                if (!$ck_unlinked_packs ||
+                                                $ck_unlinked_packs->($pid)) {
                                         $gcf2 = new();
                                         %seen = ();
                                 }
diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm
index 235a35cd..9c4d938e 100644
--- a/lib/PublicInbox/Git.pm
+++ b/lib/PublicInbox/Git.pm
@@ -24,7 +24,8 @@ use Carp qw(croak carp);
 use PublicInbox::SHA qw(sha_all);
 our %HEXLEN2SHA = (40 => 1, 64 => 256);
 our %OFMT2HEXLEN = (sha1 => 40, sha256 => 64);
-our @EXPORT_OK = qw(git_unquote git_quote %HEXLEN2SHA %OFMT2HEXLEN);
+our @EXPORT_OK = qw(git_unquote git_quote %HEXLEN2SHA %OFMT2HEXLEN
+                        $ck_unlinked_packs);
 our $in_cleanup;
 our $async_warn; # true in read-only daemons
 
@@ -597,27 +598,27 @@ sub manifest_entry {
         $ent;
 }
 
+our $ck_unlinked_packs = $^O eq 'linux' ? sub {
+        # FIXME: port gcf2-like over to git.git so we won't need to
+        # deal with libgit2
+        my $s = try_cat "/proc/$_[0]/maps";
+        $s =~ /\.(?:idx|pack) \(deleted\)/s ? 1 : undef;
+} : undef;
+
 # returns true if there are pending cat-file processes
 sub cleanup_if_unlinked {
         my ($self) = @_;
-        return cleanup($self, 1) if $^O ne 'linux';
+        $ck_unlinked_packs or return cleanup($self, 1);
         # Linux-specific /proc/$PID/maps access
         # TODO: support this inside git.git
-        my $ret = 0;
+        my $nr_live = 0;
         for my $obj ($self, ($self->{ck} // ())) {
                 my $sock = $obj->{sock} // next;
                 my $pid = $sock->attached_pid // next;
-                open my $fh, '<', "/proc/$pid/maps" or return cleanup($self, 1);
-                while (<$fh>) {
-                        # n.b. we do not restart for unlinked multi-pack-index
-                        # since it's not too huge, and the startup cost may
-                        # be higher.
-                        /\.(?:idx|pack) \(deleted\)$/ and
-                                return cleanup($self, 1);
-                }
-                ++$ret;
+                $ck_unlinked_packs->($pid) and return cleanup($self, 1);
+                ++$nr_live;
         }
-        $ret;
+        $nr_live;
 }
 
 sub event_step {