]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/DS.pm
tls: epollbit: account for miscellaneous OpenSSL errors
[public-inbox.git] / lib / PublicInbox / DS.pm
index b252ea3c141f326aa7c53c3dd8b98322df1d67d8..a02b3bb78641bd12254e718c3344a2bfef1801de 100644 (file)
@@ -40,7 +40,7 @@ my $wait_pids; # list of [ pid, callback, callback_arg ]
 my $later_queue; # list of callbacks to run at some later interval
 my $EXPMAP; # fd -> idle_time
 our $EXPTIME = 180; # 3 minutes
-my ($later_timer, $reap_armed, $reap_timer, $exp_timer);
+my ($later_timer, $reap_armed, $exp_timer);
 my $ToClose; # sockets to close when event loop is done
 our (
      %DescriptorMap,             # fd (num) -> PublicInbox::DS object
@@ -70,7 +70,7 @@ sub Reset {
     %DescriptorMap = ();
     $in_loop = $wait_pids = $later_queue = $reap_armed = undef;
     $EXPMAP = {};
-    $nextq = $ToClose = $reap_timer = $later_timer = $exp_timer = undef;
+    $nextq = $ToClose = $later_timer = $exp_timer = undef;
     $LoopTimeout = -1;  # no timeout by default
     @Timers = ();
 
@@ -240,18 +240,11 @@ sub reap_pids {
                }
        }
        # we may not be done, yet, and could've missed/masked a SIGCHLD:
-       if ($wait_pids && !$reap_armed) {
-               $reap_timer //= add_timer(1, \&reap_pids_timed);
-       }
-}
-
-sub reap_pids_timed {
-       $reap_timer = undef;
-       goto \&reap_pids;
+       $reap_armed //= requeue(\&reap_pids) if $wait_pids;
 }
 
 # reentrant SIGCHLD handler (since reap_pids is not reentrant)
-sub enqueue_reap { $reap_armed //= requeue(\&reap_pids) }
+sub enqueue_reap () { $reap_armed //= requeue(\&reap_pids) }
 
 sub in_loop () { $in_loop }
 
@@ -339,6 +332,7 @@ sub new {
 
     _InitPoller();
 
+retry:
     if (epoll_ctl($Epoll, EPOLL_CTL_ADD, $fd, $ev)) {
         if ($! == EINVAL && ($ev & EPOLLEXCLUSIVE)) {
             $ev &= ~EPOLLEXCLUSIVE;
@@ -439,7 +433,8 @@ next_buf:
                         goto next_buf;
                     }
                 } elsif ($! == EAGAIN) {
-                    epwait($sock, epbit($sock, EPOLLOUT) | EPOLLONESHOT);
+                    my $ev = epbit($sock, EPOLLOUT) or return $self->close;
+                    epwait($sock, $ev | EPOLLONESHOT);
                     return 0;
                 } else {
                     return $self->close;
@@ -475,7 +470,8 @@ sub do_read ($$$;$) {
     # common for clients to break connections without warning,
     # would be too noisy to log here:
     if ($! == EAGAIN) {
-        epwait($sock, epbit($sock, EPOLLIN) | EPOLLONESHOT);
+        my $ev = epbit($sock, EPOLLIN) or return $self->close;
+        epwait($sock, $ev | EPOLLONESHOT);
         rbuf_idle($self, $rbuf);
         0;
     } else {
@@ -549,7 +545,8 @@ sub write {
             return 1 if $written == $to_write;
             requeue($self); # runs: event_step -> flush_write
         } elsif ($! == EAGAIN) {
-            epwait($sock, epbit($sock, EPOLLOUT) | EPOLLONESHOT);
+            my $ev = epbit($sock, EPOLLOUT) or return $self->close;
+            epwait($sock, $ev | EPOLLONESHOT);
             $written = 0;
         } else {
             return $self->close;
@@ -602,7 +599,8 @@ sub accept_tls_step ($) {
     my $sock = $self->{sock} or return;
     return 1 if $sock->accept_SSL;
     return $self->close if $! != EAGAIN;
-    epwait($sock, PublicInbox::TLS::epollbit() | EPOLLONESHOT);
+    my $ev = PublicInbox::TLS::epollbit() or return $self->close;
+    epwait($sock, $ev | EPOLLONESHOT);
     unshift(@{$self->{wbuf}}, \&accept_tls_step); # autovivifies
     0;
 }
@@ -613,7 +611,8 @@ sub shutdn_tls_step ($) {
     my $sock = $self->{sock} or return;
     return $self->close if $sock->stop_SSL(SSL_fast_shutdown => 1);
     return $self->close if $! != EAGAIN;
-    epwait($sock, PublicInbox::TLS::epollbit() | EPOLLONESHOT);
+    my $ev = PublicInbox::TLS::epollbit() or return $self->close;
+    epwait($sock, $ev | EPOLLONESHOT);
     unshift(@{$self->{wbuf}}, \&shutdn_tls_step); # autovivifies
     0;
 }
@@ -636,7 +635,7 @@ sub dwaitpid ($$$) {
        push @$wait_pids, [ @_ ]; # [ $pid, $cb, $arg ]
 
        # We could've just missed our SIGCHLD, cover it, here:
-       goto &enqueue_reap; # tail recursion
+       enqueue_reap();
 }
 
 sub _run_later () {