about summary refs log tree commit homepage
path: root/lib/PublicInbox/LEI.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-10-01 09:54:29 +0000
committerEric Wong <e@80x24.org>2023-10-01 22:41:50 +0000
commit0f8926b742f8d9943ac718a0733725c1e89120fa (patch)
tree1fa25e0f2e6ef7c206ed5235a0f163dc3cc2750f /lib/PublicInbox/LEI.pm
parent2ab8795b86d0878d3f0d0830d2c178d292766e70 (diff)
downloadpublic-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.pm3
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: