Skip to content

Commit

Permalink
Rearm the CFFileDescriptor before each CFRunLoop run.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
s-ludwig committed May 28, 2020
1 parent f99ba6d commit ab829ef
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions source/eventcore/drivers/posix/cfrunloop.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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;
Expand All @@ -55,14 +56,15 @@ 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);
if (res != CFRunLoopRunResult.kCFRunLoopRunTimedOut) {
return kres || res == CFRunLoopRunResult.kCFRunLoopRunHandledSource;
}

CFFileDescriptorEnableCallBacks(m_kqueueDescriptor, CFOptionFlags.kCFFileDescriptorReadCallBack);
kres = doProcessEventsBase(0.seconds);
if (kres) break;
}
Expand All @@ -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);
}
}

0 comments on commit ab829ef

Please sign in to comment.