From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 691E21F8C8 for ; Mon, 20 Sep 2021 13:00:33 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] gcf2: fix loading at runtime Date: Mon, 20 Sep 2021 13:00:33 +0000 Message-Id: <20210920130033.3554-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: We need to waitpid synchronously on pkg-config to use $?. When loading Gcf2 inside the event loop, implicit dwaitpid done by PublicInbox::ProcessPipe would not call waitpid in time to zero $?. This was causing one of my -httpd to occasionally fall back to git(1) instead of using Gcf2. This was noted in: Link: https://public-inbox.org/meta/20210914085322.25517-1-e@80x24.org/ --- lib/PublicInbox/Gcf2.pm | 43 +++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/lib/PublicInbox/Gcf2.pm b/lib/PublicInbox/Gcf2.pm index 0d31b014..64945ca6 100644 --- a/lib/PublicInbox/Gcf2.pm +++ b/lib/PublicInbox/Gcf2.pm @@ -17,36 +17,43 @@ BEGIN { die 'PERL_INLINE_DIRECTORY not defined'; my $f = "$inline_dir/.public-inbox.lock"; open my $fh, '+>', $f or die "open($f): $!"; + + # CentOS 7.x ships Inline 0.53, 0.64+ has built-in locking + flock($fh, LOCK_EX) or die "LOCK_EX($f): $!\n"; + my $pc = which($ENV{PKG_CONFIG} // 'pkg-config') // die "pkg-config missing for libgit2"; my ($dir) = (__FILE__ =~ m!\A(.+?)/[^/]+\z!); - my $rdr = {}; - open $rdr->{2}, '>', '/dev/null' or die "open /dev/null: $!"; + my $ef = "$inline_dir/.public-inbox.pkg-config.err"; + open my $err, '+>', $ef or die "open($ef): $!"; for my $x (qw(libgit2)) { - my $l = popen_rd([$pc, '--libs', $x], undef, $rdr); + my $rdr = { 2 => $err }; + my ($l, $pid) = popen_rd([$pc, '--libs', $x], undef, $rdr); $l = do { local $/; <$l> }; + waitpid($pid, 0); next if $?; - my $c = popen_rd([$pc, '--cflags', $x], undef, $rdr); + (my $c, $pid) = popen_rd([$pc, '--cflags', $x], undef, $rdr); $c = do { local $/; <$c> }; + waitpid($pid, 0); next if $?; # note: we name C source files .h to prevent # ExtUtils::MakeMaker from automatically trying to # build them. my $f = "$dir/gcf2_$x.h"; - if (open(my $fh, '<', $f)) { - chomp($l, $c); - local $/; - defined($c_src = <$fh>) or die "read $f: $!"; - $CFG{LIBS} = $l; - $CFG{CCFLAGSEX} = $c; - last; - } else { - die "E: $f: $!"; - } + open(my $src, '<', $f) or die "E: open($f): $!"; + chomp($l, $c); + local $/; + defined($c_src = <$src>) or die "read $f: $!"; + $CFG{LIBS} = $l; + $CFG{CCFLAGSEX} = $c; + last; + } + unless ($c_src) { + seek($err, 0, SEEK_SET); + $err = do { local $/; <$err> }; + die "E: libgit2 not installed: $err\n"; } - die "E: libgit2 not installed\n" unless $c_src; - open my $oldout, '>&', \*STDOUT or die "dup(1): $!"; open my $olderr, '>&', \*STDERR or die "dup(2): $!"; open STDOUT, '>&', $fh or die "1>$f: $!"; @@ -54,14 +61,12 @@ BEGIN { STDERR->autoflush(1); STDOUT->autoflush(1); - # CentOS 7.x ships Inline 0.53, 0.64+ has built-in locking - flock($fh, LOCK_EX) or die "LOCK_EX($f): $!\n"; # we use Capitalized and ALLCAPS for compatibility with old Inline::C eval <<'EOM'; use Inline C => Config => %CFG, BOOT => q[git_libgit2_init();]; use Inline C => $c_src, BUILD_NOISY => 1; EOM - my $err = $@; + $err = $@; open(STDERR, '>&', $olderr) or warn "restore stderr: $!"; open(STDOUT, '>&', $oldout) or warn "restore stdout: $!"; if ($err) {