about summary refs log tree commit homepage
path: root/lib/PublicInbox/CmdIPC4.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-10-06 01:02:58 +0000
committerEric Wong <e@80x24.org>2023-10-06 09:38:08 +0000
commit00fe4ec336dcd8fcf3c45498d7f1ae5c228c6b92 (patch)
tree0a7d2cfe0ccd7cfd1cbc8c15017261e97ae0cb2e /lib/PublicInbox/CmdIPC4.pm
parent14dd9df0f718f8d0815851efe52f3633ec6137b8 (diff)
downloadpublic-inbox-00fe4ec336dcd8fcf3c45498d7f1ae5c228c6b92.tar.gz
This ensures script/lei $send_cmd usage is EINTR-safe (since
I prefer to avoid loading PublicInbox::IPC for startup time).
Overall, it saves us some code, too.
Diffstat (limited to 'lib/PublicInbox/CmdIPC4.pm')
-rw-r--r--lib/PublicInbox/CmdIPC4.pm24
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/PublicInbox/CmdIPC4.pm b/lib/PublicInbox/CmdIPC4.pm
index 4bc4c729..2f102ec6 100644
--- a/lib/PublicInbox/CmdIPC4.pm
+++ b/lib/PublicInbox/CmdIPC4.pm
@@ -7,6 +7,16 @@
 package PublicInbox::CmdIPC4;
 use v5.12;
 use Socket qw(SOL_SOCKET SCM_RIGHTS);
+
+sub sendmsg_retry ($) {
+        return 1 if $!{EINTR};
+        return unless ($!{ENOMEM} || $!{ENOBUFS} || $!{ETOOMANYREFS});
+        return if ++$_[0] >= 50;
+        warn "# sleeping on sendmsg: $! (#$_[0])\n";
+        select(undef, undef, undef, 0.1);
+        1;
+}
+
 BEGIN { eval {
 require Socket::MsgHdr; # XS
 no warnings 'once';
@@ -20,21 +30,21 @@ no warnings 'once';
         my $try = 0;
         do {
                 $s = Socket::MsgHdr::sendmsg($sock, $mh, $flags);
-        } while (!defined($s) &&
-                        ($!{ENOBUFS} || $!{ENOMEM} || $!{ETOOMANYREFS}) &&
-                        (++$try < 50) &&
-                        warn "# sleeping on sendmsg: $! (#$try)\n" &&
-                        select(undef, undef, undef, 0.1) == 0);
+        } while (!defined($s) && sendmsg_retry($try));
         $s;
 };
 
 *recv_cmd4 = sub ($$$) {
         my ($s, undef, $len) = @_; # $_[1] = destination buffer
         my $mh = Socket::MsgHdr->new(buflen => $len, controllen => 256);
-        my $r = Socket::MsgHdr::recvmsg($s, $mh, 0) // do {
+        my $r;
+        do {
+                $r = Socket::MsgHdr::recvmsg($s, $mh, 0);
+        } while (!defined($r) && $!{EINTR});
+        if (!defined($r)) {
                 $_[1] = '';
                 return (undef);
-        };
+        }
         $_[1] = $mh->buf;
         return () if $r == 0;
         my (undef, undef, $data) = $mh->cmsghdr;