about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--lib/PublicInbox/LEI.pm18
-rwxr-xr-xscript/lei9
2 files changed, 16 insertions, 11 deletions
diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm
index f94bfa45..2df1f326 100644
--- a/lib/PublicInbox/LEI.pm
+++ b/lib/PublicInbox/LEI.pm
@@ -1118,23 +1118,28 @@ sub dclose {
 sub event_step {
         my ($self) = @_;
         local %ENV = %{$self->{env}};
-        my $sock = $self->{sock};
         local $current_lei = $self;
         eval {
-                while (my @fds = $recv_cmd->($sock, my $buf, 4096)) {
+                my $buf;
+                while (my @fds = $recv_cmd->($self->{sock}, $buf, 4096)) {
                         if (scalar(@fds) == 1 && !defined($fds[0])) {
                                 return if $! == EAGAIN;
                                 next if $! == EINTR;
                                 last if $! == ECONNRESET;
                                 die "recvmsg: $!";
                         }
-                        for my $fd (@fds) {
-                                open my $rfh, '+<&=', $fd;
+                        for (@fds) { open my $rfh, '+<&=', $_ }
+                }
+                if ($buf eq '') {
+                        _drop_wq($self); # EOF, client disconnected
+                        dclose($self);
+                } elsif ($buf =~ /\A(STOP|CONT)\z/) {
+                        for my $wq (grep(defined, @$self{@WQ_KEYS})) {
+                                $wq->wq_kill($buf) or $wq->wq_kill_old($buf);
                         }
+                } else {
                         die "unrecognized client signal: $buf";
                 }
-                _drop_wq($self); # EOF, client disconnected
-                dclose($self);
         };
         if (my $err = $@) {
                 eval { $self->fail($err) };
@@ -1146,6 +1151,7 @@ sub event_step_init {
         my ($self) = @_;
         my $sock = $self->{sock} or return;
         $self->{-event_init_done} //= do { # persist til $ops done
+                $sock->blocking(0);
                 $self->SUPER::new($sock, EPOLLIN|EPOLLET);
                 $sock;
         };
diff --git a/script/lei b/script/lei
index 591013e3..399296ba 100755
--- a/script/lei
+++ b/script/lei
@@ -106,11 +106,10 @@ open my $dh, '<', '.' or die "open(.) $!";
 my $buf = join("\0", scalar(@ARGV), @ARGV);
 while (my ($k, $v) = each %ENV) { $buf .= "\0$k=$v" }
 $buf .= "\0\0";
-my $n = $send_cmd->($sock, [0, 1, 2, fileno($dh)], $buf, MSG_EOR);
-if (!$n) {
-        die "sendmsg: $! (check RLIMIT_NOFILE)\n" if $!{ETOOMANYREFS};
-        die "sendmsg: $!\n";
-}
+$send_cmd->($sock, [0, 1, 2, fileno($dh)], $buf, MSG_EOR) or die "sendmsg: $!";
+$SIG{TSTP} = sub { $send_cmd->($sock, [], 'STOP', MSG_EOR); kill 'STOP', $$ };
+$SIG{CONT} = sub { $send_cmd->($sock, [], 'CONT', MSG_EOR) };
+
 my $x_it_code = 0;
 while (1) {
         my (@fds) = $recv_cmd->($sock, my $buf, 4096 * 33);