diff options
author | Eric Wong <e@yhbt.net> | 2020-06-27 10:03:37 +0000 |
---|---|---|
committer | Eric Wong <e@yhbt.net> | 2020-06-28 22:27:14 +0000 |
commit | 58c0333adbdd9f5f82309cb6eef3c379f0ff064e (patch) | |
tree | 5e0d2304c4003fcd9c858db4b955abab7e6e3a8f /script | |
parent | b2b1006759730507731fcd3fc3e0de68239e3b92 (diff) | |
download | public-inbox-58c0333adbdd9f5f82309cb6eef3c379f0ff064e.tar.gz |
We can get rid of the janky wannabe self-using-a-directory-instead-of-pipe thing we needed to workaround Filesys::Notify::Simple being blocking. For existing Maildir users, this should be more robust and immune to missed wakeups for signalfd and kqueue-enabled systems; as well as being immune to BOFHs clearing $TMPDIR and preventing notifications from firing. The IMAP IDLE code still uses normal Perl signals, so it's still vulnerable to missed wakeups. That will be addressed in future commits.
Diffstat (limited to 'script')
-rwxr-xr-x | script/public-inbox-watch | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/script/public-inbox-watch b/script/public-inbox-watch index 2057066a..b6d545ad 100755 --- a/script/public-inbox-watch +++ b/script/public-inbox-watch @@ -5,6 +5,10 @@ use strict; use warnings; use PublicInbox::WatchMaildir; use PublicInbox::Config; +use PublicInbox::DS; +use PublicInbox::Sigfd; +use PublicInbox::Syscall qw(SFD_NONBLOCK); +my $oldset = PublicInbox::Sigfd::block_signals(); my ($config, $watch_md); my $reload = sub { $config = PublicInbox::Config->new; @@ -14,14 +18,22 @@ my $reload = sub { $reload->(); if ($watch_md) { my $scan = sub { $watch_md->trigger_scan('full') if $watch_md }; - $SIG{HUP} = $reload; - $SIG{USR1} = $scan; - $SIG{ALRM} = sub { $SIG{ALRM} = 'DEFAULT'; $scan->() }; - $SIG{QUIT} = $SIG{TERM} = $SIG{INT} = sub { + my $quit = sub { $watch_md->quit if $watch_md; $watch_md = undef; }; + my $sig = { HUP => $reload, USR1 => $scan }; + $sig->{QUIT} = $sig->{TERM} = $sig->{INT} = $quit; + # --no-scan is only intended for testing atm, undocumented. - alarm(1) unless (grep(/\A--no-scan\z/, @ARGV)); - $watch_md->watch while ($watch_md); + unless (grep(/\A--no-scan\z/, @ARGV)) { + PublicInbox::DS::requeue($scan); + } + my $sigfd = PublicInbox::Sigfd->new($sig, SFD_NONBLOCK); + local %SIG = (%SIG, %$sig) if !$sigfd; + if (!$sigfd) { + PublicInbox::Sigfd::set_sigmask($oldset); + PublicInbox::DS->SetLoopTimeout(1000); + } + $watch_md->watch($sig, $oldset) while ($watch_md); } |