about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-12-26 03:05:15 +0000
committerEric Wong <e@80x24.org>2016-12-26 03:05:36 +0000
commit427245acacaf04a882d5524e662075909b96905b (patch)
tree6a50ffc3026ab512593ee4c80afbf787a3f39dc5
parentd0164b3c9048bfd733a82b8fcd53d032e97552cc (diff)
downloadpublic-inbox-427245acacaf04a882d5524e662075909b96905b.tar.gz
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.
-rw-r--r--lib/PublicInbox/EvCleanup.pm14
1 files changed, 12 insertions, 2 deletions
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 {