]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
xap_client: spawn C++ xap_helper directly
authorEric Wong <e@80x24.org>
Mon, 13 Nov 2023 13:15:40 +0000 (13:15 +0000)
committerEric Wong <e@80x24.org>
Mon, 13 Nov 2023 21:54:59 +0000 (21:54 +0000)
No need to suffer through an extra dose of slow Perl load times
when we can drive the build in the big parent Perl process and
get the executable path name to pass to spawn directly.

lib/PublicInbox/XapClient.pm
lib/PublicInbox/XapHelperCxx.pm
t/xap_helper.t

index 21c8926545bb0598784badc34edfd563767ec11e..dda5e044b3533991e7b9499b7464ba3cee51f43a 100644 (file)
@@ -11,7 +11,7 @@ use v5.12;
 use PublicInbox::Spawn qw(spawn);
 use Socket qw(AF_UNIX SOCK_SEQPACKET);
 use PublicInbox::IPC;
-use autodie qw(pipe socketpair);
+use autodie qw(fork pipe socketpair);
 
 sub mkreq {
        my ($self, $ios, @arg) = @_;
@@ -28,19 +28,19 @@ sub mkreq {
 sub start_helper {
        my @argv = @_;
        socketpair(my $sock, my $in, AF_UNIX, SOCK_SEQPACKET, 0);
-       my $cls = ($ENV{PI_NO_CXX} ? undef : eval {
-                       require PublicInbox::XapHelperCxx;
-                       PublicInbox::XapHelperCxx::check_build();
-                       'PublicInbox::XapHelperCxx';
-               }) // do {
-                       require PublicInbox::XapHelper;
-                       'PublicInbox::XapHelper';
-               };
-       # ensure the child process has the same @INC we do:
-       my $env = { PERL5LIB => join(':', @INC) };
-       my $pid = spawn([$^X, ($^W ? ('-w') : ()), "-M$cls", '-e',
-                               $cls.'::start(@ARGV)', '--', @argv],
-                       $env, { 0 => $in });
+       require PublicInbox::XapHelperCxx;
+       my $cls = 'PublicInbox::XapHelperCxx';
+       my $env;
+       my $cmd = eval { PublicInbox::XapHelperCxx::cmd() };
+       if ($@) { # fall back to Perl + XS|SWIG
+               require PublicInbox::XapHelper;
+               $cls = 'PublicInbox::XapHelper';
+               # ensure the child process has the same @INC we do:
+               $env = { PERL5LIB => join(':', @INC) };
+               $cmd = [$^X, ($^W ? ('-w') : ()), "-M$cls", '-e',
+                       $cls.'::start(@ARGV)', '--' ];
+       }
+       my $pid = spawn($cmd, $env, { 0 => $in });
        ((bless { io => $sock, impl => $cls }, __PACKAGE__), $pid);
 }
 
index 3afdd69ee7414684439e63997effc553d975cad8..e516b1118466445401279a29f0f535f61da02831 100644 (file)
@@ -114,17 +114,16 @@ sub check_build () {
        needs_rebuild() ? build() : 0;
 }
 
-sub start (@) {
+# returns spawn arg
+sub cmd {
        check_build();
        my @cmd;
        if (my $v = $ENV{VALGRIND}) {
                $v = 'valgrind -v' if $v eq '1';
                @cmd = split(/\s+/, $v);
        }
-       push @cmd, $bin, @_;
-       my $prog = $cmd[0];
-       $cmd[0] =~ s!\A.*?/([^/]+)\z!$1!;
-       exec { $prog } @cmd;
+       push @cmd, $bin;
+       \@cmd;
 }
 
 1;
index 7890392d36ea7fb118fb68ece319aec1c38f4d53..83f59d7d70908cbc520dc8e0d065268a55c37506 100644 (file)
@@ -61,11 +61,11 @@ my $doreq = sub {
 
 my $env = { PERL5LIB => join(':', @INC) };
 my $test = sub {
-       my (@arg) = @_;
+       my (@cmd) = @_;
        socketpair(my $s, my $y, AF_UNIX, SOCK_SEQPACKET, 0);
-       my $pid = spawn([$^X, '-w', @arg], $env, { 0 => $y });
+       my $pid = spawn(\@cmd, $env, { 0 => $y });
        my $ar = PublicInbox::AutoReap->new($pid);
-       diag "$arg[-1] running pid=$pid";
+       diag "$cmd[-1] running pid=$pid";
        close $y;
        my $r = $doreq->($s, qw(test_inspect -d), $ibx_idx[0]);
        my %info = map { split(/=/, $_, 2) } split(/ /, do { local $/; <$r> });
@@ -141,24 +141,20 @@ my $test = sub {
 
 my @NO_CXX = (1);
 unless ($ENV{TEST_XH_CXX_ONLY}) {
-       my $ar = $test->(qw[-MPublicInbox::XapHelper -e
+       my $ar = $test->($^X, qw[-w -MPublicInbox::XapHelper -e
                        PublicInbox::XapHelper::start('-j0')]);
-       ($ar, my $s) = $test->(qw[-MPublicInbox::XapHelper -e
+       ($ar, my $s) = $test->($^X, qw[-w -MPublicInbox::XapHelper -e
                        PublicInbox::XapHelper::start('-j1')]);
        no_pollerfd($ar->{pid});
 }
 SKIP: {
-       eval {
-               require PublicInbox::XapHelperCxx;
-               PublicInbox::XapHelperCxx::check_build();
-       };
+       require PublicInbox::XapHelperCxx;
+       my $cmd = eval { PublicInbox::XapHelperCxx::cmd() };
        skip "XapHelperCxx build: $@", 1 if $@ || $ENV{PI_NO_CXX};
 
        @NO_CXX = $ENV{TEST_XH_CXX_ONLY} ? (0) : (0, 1);
-       my $ar = $test->(qw[-MPublicInbox::XapHelperCxx -e
-                       PublicInbox::XapHelperCxx::start('-j0')]);
-       $ar = $test->(qw[-MPublicInbox::XapHelperCxx -e
-                       PublicInbox::XapHelperCxx::start('-j1')]);
+       my $ar = $test->(@$cmd, '-j0');
+       $ar = $test->(@$cmd, '-j1');
 };
 
 require PublicInbox::CodeSearch;