]> Sergey Matveev's repositories - public-inbox.git/commitdiff
ds: share watch_chg between watch_read/watch_write
authorEric Wong <e@80x24.org>
Mon, 24 Jun 2019 02:52:20 +0000 (02:52 +0000)
committerEric Wong <e@80x24.org>
Mon, 24 Jun 2019 05:26:26 +0000 (05:26 +0000)
There was much duplicate logic between watch_read and
watch_write.  Share that logic, and give us room to enable
edge-triggered or one-shot notifications in the future.

lib/PublicInbox/DS.pm

index 00e2e5c6bb017e2070700dae82d3bdf0fc2d6b36..943e30b52e8c40560eb9ca87755d513d5e857005 100644 (file)
@@ -622,65 +622,42 @@ sub msg_more ($$) {
     $self->write(\($_[1]));
 }
 
-=head2 C<< $obj->watch_read( $boolean ) >>
-
-Turn 'readable' event notification on or off.
-
-=cut
-sub watch_read {
-    my PublicInbox::DS $self = shift;
+sub watch_chg ($$$) {
+    my ($self, $bits, $set) = @_;
     my $sock = $self->{sock} or return;
-
-    my $val = shift;
-    my $event = $self->{event_watch};
-
-    $event &= ~EPOLLIN if ! $val;
-    $event |=  EPOLLIN if   $val;
-
+    my $cur = $self->{event_watch};
+    my $changes = $cur;
+    if ($set) {
+        $changes |= $bits;
+    } else {
+        $changes &= ~$bits;
+    }
+    return if $changes == $cur;
     my $fd = fileno($sock);
-    # If it changed, set it
-    if ($event != $self->{event_watch}) {
-        if ($HaveKQueue) {
-            $KQueue->EV_SET($fd, EVFILT_READ(),
-                            $val ? EV_ENABLE() : EV_DISABLE());
-        }
-        elsif ($HaveEpoll) {
-            epoll_ctl($Epoll, EPOLL_CTL_MOD, $fd, $event) and
-                confess("EPOLL_CTL_MOD: $!");
-        }
-        $self->{event_watch} = $event;
+    if ($HaveEpoll) {
+        epoll_ctl($Epoll, EPOLL_CTL_MOD, $fd, $changes) and
+            confess("EPOLL_CTL_MOD $!");
+    } elsif ($HaveKQueue) {
+        my $flag = $set ? EV_ENABLE() : EV_DISABLE();
+        $KQueue->EV_SET($fd, EVFILT_READ(), $flag) if $bits & EPOLLIN;
+        $KQueue->EV_SET($fd, EVFILT_WRITE(), $flag) if $bits & EPOLLOUT;
     }
+    $self->{event_watch} = $changes;
 }
 
-=head2 C<< $obj->watch_write( $boolean ) >>
+=head2 C<< $obj->watch_read( $boolean ) >>
 
-Turn 'writable' event notification on or off.
+Turn 'readable' event notification on or off.
 
 =cut
-sub watch_write {
-    my PublicInbox::DS $self = shift;
-    my $sock = $self->{sock} or return;
+sub watch_read ($$) { watch_chg($_[0], EPOLLIN, $_[1]) };
 
-    my $val = shift;
-    my $event = $self->{event_watch};
+=head2 C<< $obj->watch_write( $boolean ) >>
 
-    $event &= ~EPOLLOUT if ! $val;
-    $event |=  EPOLLOUT if   $val;
-    my $fd = fileno($sock);
+Turn 'writable' event notification on or off.
 
-    # If it changed, set it
-    if ($event != $self->{event_watch}) {
-        if ($HaveKQueue) {
-            $KQueue->EV_SET($fd, EVFILT_WRITE(),
-                            $val ? EV_ENABLE() : EV_DISABLE());
-        }
-        elsif ($HaveEpoll) {
-            epoll_ctl($Epoll, EPOLL_CTL_MOD, $fd, $event) and
-                    confess "EPOLL_CTL_MOD: $!";
-        }
-        $self->{event_watch} = $event;
-    }
-}
+=cut
+sub watch_write ($$) { watch_chg($_[0], EPOLLOUT, $_[1]) };
 
 package PublicInbox::DS::Timer;
 # [$abs_float_firetime, $coderef];