about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@yhbt.net>2020-01-12 21:17:56 +0000
committerEric Wong <e@yhbt.net>2020-01-13 23:21:32 +0000
commit8cb2a4307b20868266c838fc940bc8a57bca968a (patch)
tree3e7f2ea32b6fc8917c9b15b8194433440d82ab3b
parent8775167475d8bfc25d532b777147a8b1ef1cd99b (diff)
downloadpublic-inbox-8cb2a4307b20868266c838fc940bc8a57bca968a.tar.gz
We can use the return value of sysread to bound our loop instead
of repeatedly shortening the string.  Furthermore add some
comments which can be easily checked against the signalfd(2)
manpage.
-rw-r--r--lib/PublicInbox/Sigfd.pm13
1 files changed, 7 insertions, 6 deletions
diff --git a/lib/PublicInbox/Sigfd.pm b/lib/PublicInbox/Sigfd.pm
index ec5d7145..15dedb10 100644
--- a/lib/PublicInbox/Sigfd.pm
+++ b/lib/PublicInbox/Sigfd.pm
@@ -42,14 +42,15 @@ sub new {
 # PublicInbox::Daemon in master main loop (blocking)
 sub wait_once ($) {
         my ($self) = @_;
+        # 128 == sizeof(struct signalfd_siginfo)
         my $r = sysread($self->{sock}, my $buf, 128 * 64);
         if (defined($r)) {
-                while (1) {
-                        my $sig = unpack('L', $buf);
-                        my $cb = $self->{sig}->{$sig};
-                        $cb->($sig) if $cb ne 'IGNORE';
-                        return $r if length($buf) == 128;
-                        $buf = substr($buf, 128);
+                my $nr = $r / 128 - 1; # $nr may be -1
+                for my $off (0..$nr) {
+                        # the first uint32_t of signalfd_siginfo: ssi_signo
+                        my $signo = unpack('L', substr($buf, 128 * $off, 4));
+                        my $cb = $self->{sig}->{$signo};
+                        $cb->($signo) if $cb ne 'IGNORE';
                 }
         }
         $r;