diff options
author | Eric Wong <e@80x24.org> | 2019-06-28 05:25:40 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2019-06-29 19:59:00 +0000 |
commit | 7c83d3e706811095cedab0bf62ac530d7b0f3a5a (patch) | |
tree | 14492c1fd2e0f567b70e691ffd75fb88a28a238c /lib/PublicInbox/DS.pm | |
parent | e37ac4015fa6f9616c845a73abc36ec5a21d57a7 (diff) | |
download | public-inbox-7c83d3e706811095cedab0bf62ac530d7b0f3a5a.tar.gz |
ds: handle deferred DS->close after timers
Our hacks in EvCleanup::next_tick and EvCleanup::asap were due to the fact "closed" sockets were deferred and could not wake up the event loop, causing certain actions to be delayed until an event fired. Instead, ensure we don't sleep if there are pending sockets to close. We can then remove most of the EvCleanup stuff While we're at it, split out immediate timer handling into a separate array so we don't need to deal with time calculations for the event loop.
Diffstat (limited to 'lib/PublicInbox/DS.pm')
-rw-r--r-- | lib/PublicInbox/DS.pm | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index 8f1494f6..6cd527e2 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -37,7 +37,6 @@ use Errno qw(EAGAIN EINVAL EEXIST); use Carp qw(croak confess carp); require File::Spec; -my $nextt; # timer for next_tick my $nextq = []; # queue for next_tick our ( %DescriptorMap, # fd (num) -> PublicInbox::DS object @@ -101,12 +100,6 @@ Returns a timer object which you can call C<< $timer->cancel >> on if you need t sub AddTimer { my ($class, $secs, $coderef) = @_; - if (!$secs) { - my $timer = bless([0, $coderef], 'PublicInbox::DS::Timer'); - unshift(@Timers, $timer); - return $timer; - } - my $fire_time = now() + $secs; my $timer = bless [$fire_time, $coderef], "PublicInbox::DS::Timer"; @@ -176,9 +169,23 @@ sub FirstTimeEventLoop { sub now () { clock_gettime(CLOCK_MONOTONIC) } +sub next_tick () { + my $q = $nextq; + $nextq = []; + for (@$q) { + if (ref($_) eq 'CODE') { + $_->(); + } else { + $_->event_step; + } + } +} + # runs timers and returns milliseconds for next one, or next event loop sub RunTimers { - return $LoopTimeout unless @Timers; + next_tick(); + + return ((@$nextq || @ToClose) ? 0 : $LoopTimeout) unless @Timers; my $now = now(); @@ -188,6 +195,9 @@ sub RunTimers { $to_run->[1]->($now) if $to_run->[1]; } + # timers may enqueue into nextq: + return 0 if (@$nextq || @ToClose); + return $LoopTimeout unless @Timers; # convert time to an even number of milliseconds, adding 1 @@ -320,6 +330,8 @@ sub new { ### I N S T A N C E M E T H O D S ##################################################################### +sub requeue ($) { push @$nextq, $_[0] } + =head2 C<< $obj->close >> Close the socket. @@ -593,19 +605,6 @@ sub shutdn ($) { $self->close; } } - -sub next_tick () { - $nextt = undef; - my $q = $nextq; - $nextq = []; - $_->event_step for @$q; -} - -sub requeue ($) { - push @$nextq, $_[0]; - $nextt ||= PublicInbox::EvCleanup::asap(*next_tick); -} - package PublicInbox::DS::Timer; # [$abs_float_firetime, $coderef]; sub cancel { |