From ab829efc7c011dae8f55c7c7306ef2ee8bb2cc56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Thu, 28 May 2020 16:43:20 +0200 Subject: [PATCH] Rearm the CFFileDescriptor before each CFRunLoop run. Instead of rearming from within the callback, this enables the callback before the event loop is run and before the kqueue is cleared. This at least heavily reduces the cases where the CFRunLoop hangs instead of reporting a pending kqueue event. For this reason, the safety timeout has been increased to 5 seconds. --- source/eventcore/drivers/posix/cfrunloop.d | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/eventcore/drivers/posix/cfrunloop.d b/source/eventcore/drivers/posix/cfrunloop.d index 6fbcbe7b..22d4e99d 100644 --- a/source/eventcore/drivers/posix/cfrunloop.d +++ b/source/eventcore/drivers/posix/cfrunloop.d @@ -31,7 +31,6 @@ final class CFRunLoopEventLoop : KqueueEventLoopBase { m_kqueueDescriptor = CFFileDescriptorCreate(kCFAllocatorDefault, m_queue, false, &processKqueue, &ctx); - CFFileDescriptorEnableCallBacks(m_kqueueDescriptor, CFOptionFlags.kCFFileDescriptorReadCallBack); m_kqueueSource = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, m_kqueueDescriptor, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), m_kqueueSource, kCFRunLoopDefaultMode); } @@ -40,6 +39,8 @@ final class CFRunLoopEventLoop : KqueueEventLoopBase { @trusted { import std.algorithm.comparison : min; + CFFileDescriptorEnableCallBacks(m_kqueueDescriptor, CFOptionFlags.kCFFileDescriptorReadCallBack); + // submit changes and process pending events auto kres = doProcessEventsBase(0.seconds); if (kres) timeout = 0.seconds; @@ -55,7 +56,7 @@ final class CFRunLoopEventLoop : KqueueEventLoopBase { // events does not help (and is also eplicitly discouraged in // Apple's documentation). while (timeout > 0.seconds) { - auto tol = min(timeout, 1.seconds); + auto tol = min(timeout, 5.seconds); timeout -= tol; CFTimeInterval to = 1e-7 * tol.total!"hnsecs"; auto res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, to, true); @@ -63,6 +64,7 @@ final class CFRunLoopEventLoop : KqueueEventLoopBase { return kres || res == CFRunLoopRunResult.kCFRunLoopRunHandledSource; } + CFFileDescriptorEnableCallBacks(m_kqueueDescriptor, CFOptionFlags.kCFFileDescriptorReadCallBack); kres = doProcessEventsBase(0.seconds); if (kres) break; } @@ -83,7 +85,6 @@ final class CFRunLoopEventLoop : KqueueEventLoopBase { CFOptionFlags callBackTypes, void* info) { auto this_ = () @trusted { return cast(CFRunLoopEventLoop)info; } (); - auto res = this_.doProcessEventsBase(0.seconds); - () @trusted { CFFileDescriptorEnableCallBacks(this_.m_kqueueDescriptor, CFOptionFlags.kCFFileDescriptorReadCallBack); } (); + this_.doProcessEventsBase(0.seconds); } }