diff options
author | Eric Wong <e@80x24.org> | 2019-11-24 00:22:30 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2019-11-24 21:35:19 +0000 |
commit | 8576a48b2344905229737fde45498c80a1171ca5 (patch) | |
tree | 0ff343124cd1498415babfd8b74efc827c56b6c7 /lib/PublicInbox/Daemon.pm | |
parent | 34a51e5736d7d1b7d2da7f7640eb2b87eec121ff (diff) | |
download | public-inbox-8576a48b2344905229737fde45498c80a1171ca5.tar.gz |
While the master process has a self-pipe to avoid missing signals, worker processes lack that aside from a pipe to detect master death. That pipe doesn't exist when there's no master process, so it's possible DS::close never finishes because it never woke up from epoll_wait. So create a pipe on the worker_quit signal and force it into epoll/kevent so it wakes up right away.
Diffstat (limited to 'lib/PublicInbox/Daemon.pm')
-rw-r--r-- | lib/PublicInbox/Daemon.pm | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/PublicInbox/Daemon.pm b/lib/PublicInbox/Daemon.pm index 90f11137..0e3b95d2 100644 --- a/lib/PublicInbox/Daemon.pm +++ b/lib/PublicInbox/Daemon.pm @@ -252,6 +252,11 @@ sub daemonize () { } } +sub shrink_pipes { + if ($^O eq 'linux') { # 1031: F_SETPIPE_SZ, 4096: page size + fcntl($_, 1031, 4096) for @_; + } +} sub worker_quit { # killing again terminates immediately: @@ -260,6 +265,17 @@ sub worker_quit { $_->close foreach @listeners; # call PublicInbox::DS::close @listeners = (); + # create a lazy self-pipe which kicks us out of the EventLoop + # so DS::PostEventLoop can fire + if (pipe(my ($r, $w))) { + shrink_pipes($w); + + # shrink_pipes == noop + PublicInbox::ParentPipe->new($r, *shrink_pipes); + close $w; # wake up from the event loop + } else { + warn "E: pipe failed ($!), quit unreliable\n"; + } my $proc_name; my $warn = 0; # drop idle connections and try to quit gracefully @@ -468,10 +484,7 @@ sub unlink_pid_file_safe_ish ($$) { sub master_loop { pipe(my ($p0, $p1)) or die "failed to create parent-pipe: $!"; pipe(my ($r, $w)) or die "failed to create self-pipe: $!"; - - if ($^O eq 'linux') { # 1031: F_SETPIPE_SZ = 1031 - fcntl($_, 1031, 4096) for ($w, $p1); - } + shrink_pipes($w, $p1); IO::Handle::blocking($w, 0); my $set_workers = $worker_processes; |