X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FDS.pm;h=a02b3bb78641bd12254e718c3344a2bfef1801de;hb=31f9b61a318f4daf8a6208ed4f6bc60aa355faa9;hp=b252ea3c141f326aa7c53c3dd8b98322df1d67d8;hpb=8aec4e8ddea9d9002be2d6af0849d8c5eb84b2e7;p=public-inbox.git diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index b252ea3c..a02b3bb7 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -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 () {