]> Sergey Matveev's repositories - public-inbox.git/commitdiff
watch: retry signals to kill IDLE and polling processes
authorEric Wong <e@yhbt.net>
Wed, 1 Jul 2020 21:06:17 +0000 (21:06 +0000)
committerEric Wong <e@yhbt.net>
Thu, 2 Jul 2020 20:36:20 +0000 (20:36 +0000)
To ensure reliable signal delivery in Perl, it seems we need to
repeatedly signal processes which aren't using signalfd (or
EVFILT_SIGNAL) with our event loop.

lib/PublicInbox/WatchMaildir.pm

index e3df85159e7d9af50d93c7ce3f9d7dd9b0701ef4..23b2e9f110b759814017146a559d4c8484741e55 100644 (file)
@@ -202,18 +202,27 @@ sub _try_path {
        }
 }
 
+sub quit_done ($) {
+       my ($self) = @_;
+       return unless $self->{quit};
+
+       # don't have reliable wakeups, keep signalling
+       my $done = 1;
+       for (qw(idle_pids poll_pids)) {
+               my $pids = $self->{$_} or next;
+               for (keys %$pids) {
+                       $done = undef if kill('QUIT', $_);
+               }
+       }
+       $done;
+}
+
 sub quit {
        my ($self) = @_;
        $self->{quit} = 1;
        %{$self->{opendirs}} = ();
        _done_for_now($self);
-       if (my $imap_pid = $self->{-imap_pid}) {
-               kill('QUIT', $imap_pid);
-       }
-       for (qw(idle_pids poll_pids)) {
-               my $pids = $self->{$_} or next;
-               kill('QUIT', $_) for (keys %$pids);
-       }
+       quit_done($self);
        if (my $idle_mic = $self->{idle_mic}) {
                eval { $idle_mic->done };
                if ($@) {
@@ -921,8 +930,8 @@ sub watch {
                                                [$self, $intvl, $urls]);
        }
        watch_fs_init($self) if $self->{mdre};
-       PublicInbox::DS->SetPostLoopCallback(sub {});
-       PublicInbox::DS->EventLoop until $self->{quit};
+       PublicInbox::DS->SetPostLoopCallback(sub { !$self->quit_done });
+       PublicInbox::DS->EventLoop;
        _done_for_now($self);
 }