From 427245acacaf04a882d5524e662075909b96905b Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 26 Dec 2016 03:05:15 +0000 Subject: evcleanup: ensure deferred close from timers are handled ASAP 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 | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/PublicInbox/EvCleanup.pm b/lib/PublicInbox/EvCleanup.pm index 2b77c617..b9fe843b 100644 --- a/lib/PublicInbox/EvCleanup.pm +++ b/lib/PublicInbox/EvCleanup.pm @@ -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 { -- cgit v1.2.3-24-ge0c7