diff options
author | Eric Wong <e@80x24.org> | 2023-10-01 09:54:29 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2023-10-01 22:41:50 +0000 |
commit | 0f8926b742f8d9943ac718a0733725c1e89120fa (patch) | |
tree | 1fa25e0f2e6ef7c206ed5235a0f163dc3cc2750f /lib/PublicInbox/LEI.pm | |
parent | 2ab8795b86d0878d3f0d0830d2c178d292766e70 (diff) | |
download | public-inbox-0f8926b742f8d9943ac718a0733725c1e89120fa.tar.gz |
lei/store can get stuck if lei-daemon is blocked, and lei-daemon can get stuck when a clients stderr is redirected to a pager that isn't consumed. So start relying on Time::HiRes::alarm to generate SIGALRM to break out of the `print' perlop. Unfortunately, this isn't easy since Perl auto-restarts all writes, so we dup(2) the destination FD and close the copy in the SIGALRM handler to force `print' to return. Most programs (MUAs, editors, etc.) aren't equipped to deal with non-blocking STDERR, so we can't make the stderr file description non-blocking. Another way to solve this problem would be to have script/lei send a non-blocking pipe to lei-daemon in the {2} slot and make script/lei splice messages from the pipe to stderr. Unfortunately, that requires more work and forces more complexity into script/lei and slow down normal cases where stderr doesn't get blocked.
Diffstat (limited to 'lib/PublicInbox/LEI.pm')
-rw-r--r-- | lib/PublicInbox/LEI.pm | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 1899bf38..06bc7ebd 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -1287,7 +1287,7 @@ sub lazy_start { undef $lk; my @st = stat($path) or die "stat($path): $!"; my $dev_ino_expect = pack('dd', $st[0], $st[1]); # dev+ino - local $oldset = PublicInbox::DS::block_signals(); + local $oldset = PublicInbox::DS::block_signals(POSIX::SIGALRM); die "incompatible narg=$narg" if $narg != 5; $PublicInbox::IPC::send_cmd or die <<""; (Socket::MsgHdr || Inline::C) missing/unconfigured (narg=$narg); @@ -1369,6 +1369,7 @@ sub lazy_start { strftime('%Y-%m-%dT%H:%M:%SZ', gmtime(time))," $$ ", @_); }; local $SIG{PIPE} = 'IGNORE'; + local $SIG{ALRM} = 'IGNORE'; open STDERR, '>&STDIN' or die "redirect stderr failed: $!"; open STDOUT, '>&STDIN' or die "redirect stdout failed: $!"; # $daemon pipe to `lei' closed, main loop begins: |