]> Sergey Matveev's repositories - public-inbox.git/commitdiff
evcleanup: ensure deferred close from timers are handled ASAP
authorEric Wong <e@80x24.org>
Mon, 26 Dec 2016 03:05:15 +0000 (03:05 +0000)
committerEric Wong <e@80x24.org>
Mon, 26 Dec 2016 03:05:36 +0000 (03:05 +0000)
Danga::Socket defers close() syscalls until the end of the event
loop to avoid FD recycling.  Unfortunately, this is dependent on
IO events firing and waking the process up from
poll/kevent/epoll_wait.

Without any I/O activity, a socket could remain in the
@Danga::Socket::ToClose array indefinitely.  Thus, we will
trigger a fake IO event after running all timers to trigger
the deferred close in Danga::Socket::PostEventLoop.

lib/PublicInbox/EvCleanup.pm

index 2b77c617b24f6485c26890b0e6e471209bd26b8b..b9fe843b18a7bcb9ae97777d99bdc16984426973 100644 (file)
@@ -30,9 +30,19 @@ sub _run_all ($) {
        $_->() foreach @$run;
 }
 
+# ensure Danga::Socket::ToClose fires after timers fire
+sub _asap_close () { $asapq->[1] ||= _asap_timer() }
+
 sub _run_asap () { _run_all($asapq) }
-sub _run_next () { _run_all($nextq) }
-sub _run_later () { _run_all($laterq) }
+sub _run_next () {
+       _run_all($nextq);
+       _asap_close();
+}
+
+sub _run_later () {
+       _run_all($laterq);
+       _asap_close();
+}
 
 # Called by Danga::Socket
 sub event_write {