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 | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/lib/PublicInbox/CodeSearchIdx.pm b/lib/PublicInbox/CodeSearchIdx.pm
index 0a6b8fce..22097d03 100644
--- a/lib/PublicInbox/CodeSearchIdx.pm
+++ b/lib/PublicInbox/CodeSearchIdx.pm
@@ -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;

Reply via email to