It saves some code in case we keep libgit2 around.
---
 lib/PublicInbox/Gcf2.pm | 16 ++++------------
 lib/PublicInbox/Git.pm  | 27 ++++++++++++++-------------
 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 {

Reply via email to