]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
cindex: fix --no-scan no-op non-termination
authorEric Wong <e@80x24.org>
Tue, 9 May 2023 09:15:30 +0000 (09:15 +0000)
committerEric Wong <e@80x24.org>
Tue, 9 May 2023 20:57:57 +0000 (20:57 +0000)
We must account for the shards_active() recursing upon itself
when outside DS->event_loop.  This is tricky, unfortunately, but
--no-scan isn't a common mode of operation.  Noticed while
developing the monster --associate functionality to
automatically create bidirectional associations of
inboxes/extindices to coderepos.

lib/PublicInbox/CodeSearchIdx.pm

index 0a6b8fce24cfe343c1b2fce8661c9a1a7d10c946..22097d03bf1b07416444f3185b0870d572cb9027 100644 (file)
@@ -628,11 +628,6 @@ EOM
 
 sub scan_git_dirs ($) {
        my ($self) = @_;
-
-       # FreeBSD ignores/discards SIGCHLD while signals are blocked and
-       # EVFILT_SIGNAL is inactive, so we pretend we have a SIGCHLD pending
-       PublicInbox::DS::enqueue_reap();
-
        @$GIT_TODO = @{$self->{git_dirs}};
        index_next($self) for (1..$LIVE_JOBS);
 }
@@ -668,8 +663,8 @@ sub shards_active { # post_loop_do
        return 1 if scalar(@$GIT_TODO) || scalar(@$IDX_TODO) || $REPO_CTX;
        return 1 if keys(%$LIVE);
        for my $s (grep { $_->{-wq_s1} } @IDX_SHARDS) {
-               $s->{-cidx_quit} = 1;
-               $s->wq_close;
+               $s->{-cidx_quit} = 1 if defined($s->{-wq_s1});
+               $s->wq_close; # may recurse via awaitpid outside of event_loop
        }
        scalar(grep { $_->{-cidx_quit} } @IDX_SHARDS);
 }
@@ -927,6 +922,10 @@ sub cidx_run { # main entry point
        init_prune($self);
        scan_git_dirs($self) if $self->{-opt}->{scan} // 1;
 
+       # FreeBSD ignores/discards SIGCHLD while signals are blocked and
+       # EVFILT_SIGNAL is inactive, so we pretend we have a SIGCHLD pending
+       PublicInbox::DS::enqueue_reap();
+
        local @PublicInbox::DS::post_loop_do = (\&shards_active);
        PublicInbox::DS::event_loop($MY_SIG, $SIGSET) if shards_active();
        PublicInbox::DS->Reset;