]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/DS.pm
ds: always use EV_ADD with EV_SET
[public-inbox.git] / lib / PublicInbox / DS.pm
index 044b991c8c602abbee79a7b947ac3a21bacae50b..8f77ce24b20ed5171f30720d88c83469fe2b28d7 100644 (file)
@@ -293,8 +293,8 @@ sub PostEventLoop {
     while (my $sock = shift @ToClose) {
         my $fd = fileno($sock);
 
-        # close the socket.  (not a PublicInbox::DS close)
-        $sock->close;
+        # close the socket. (not a PublicInbox::DS close)
+        CORE::close($sock);
 
         # and now we can finally remove the fd from the map.  see
         # comment above in ->close.
@@ -321,7 +321,7 @@ sub kq_flag ($$) {
         my $fl = EV_ADD() | EV_ENABLE();
         ($ev & EPOLLONESHOT) ? ($fl|EV_ONESHOT()) : $fl;
     } else {
-        EV_DISABLE();
+        EV_ADD() | EV_DISABLE();
     }
 }
 
@@ -364,8 +364,8 @@ retry:
         }
     }
     elsif ($HaveKQueue) {
-        $KQueue->EV_SET($fd, EVFILT_READ(), EV_ADD() | kq_flag(EPOLLIN, $ev));
-        $KQueue->EV_SET($fd, EVFILT_WRITE(), EV_ADD() | kq_flag(EPOLLOUT, $ev));
+        $KQueue->EV_SET($fd, EVFILT_READ(), kq_flag(EPOLLIN, $ev));
+        $KQueue->EV_SET($fd, EVFILT_WRITE(), kq_flag(EPOLLOUT, $ev));
     }
 
     Carp::cluck("PublicInbox::DS::new blowing away existing descriptor map for fd=$fd ($DescriptorMap{$fd})")
@@ -537,7 +537,8 @@ sub write {
     my $sock = $self->{sock} or return 1;
     my $ref = ref $data;
     my $bref = $ref ? $data : \$data;
-    if (my $wbuf = $self->{wbuf}) { # already buffering, can't write more...
+    my $wbuf = $self->{wbuf};
+    if ($wbuf && scalar(@$wbuf)) { # already buffering, can't write more...
         if ($ref eq 'CODE') {
             push @$wbuf, $bref;
         } else {
@@ -621,6 +622,30 @@ sub accept_tls_step ($) {
     drop($self, 'BUG? EAGAIN but '.PublicInbox::TLS::err());
 }
 
+sub shutdn_tls_step ($) {
+    my ($self) = @_;
+    my $sock = $self->{sock} or return;
+    return $self->close if $sock->stop_SSL(SSL_fast_shutdown => 1);
+    return $self->close if $! != EAGAIN;
+    if (my $ev = PublicInbox::TLS::epollbit()) {
+        unshift @{$self->{wbuf} ||= []}, \&shutdn_tls_step;
+        return watch($self, $ev | EPOLLONESHOT);
+    }
+    drop($self, 'BUG? EAGAIN but '.PublicInbox::TLS::err());
+}
+
+# don't bother with shutdown($sock, 2), we don't fork+exec w/o CLOEXEC
+# or fork w/o exec, so no inadvertant socket sharing
+sub shutdn ($) {
+    my ($self) = @_;
+    my $sock = $self->{sock} or return;
+    if (ref($sock) eq 'IO::Socket::SSL') {
+        shutdn_tls_step($self);
+    } else {
+       $self->close;
+    }
+}
+
 package PublicInbox::DS::Timer;
 # [$abs_float_firetime, $coderef];
 sub cancel {