Merge pull request #147 from vibe-d/fix_cfrunloop_hang
Work around possible hang of CFRunLoop with pending kqueue events.
This commit is contained in:
commit
72cb27bb93
|
@ -25,6 +25,11 @@ final class CFRunLoopEventLoop : KqueueEventLoopBase {
|
||||||
@trusted @nogc {
|
@trusted @nogc {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
// Edge-triggred mode is not fully reliable w.r.t. the CFFileDescriptor
|
||||||
|
// firing the callback for some reason. Always using level-triggered
|
||||||
|
// kqueue events avoids possible hangs during CFRunLoopInMode
|
||||||
|
m_forceLevelTriggered = true;
|
||||||
|
|
||||||
CFFileDescriptorContext ctx;
|
CFFileDescriptorContext ctx;
|
||||||
ctx.info = cast(void*)this;
|
ctx.info = cast(void*)this;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ abstract class KqueueEventLoopBase : PosixEventLoop {
|
||||||
size_t m_changeCount = 0;
|
size_t m_changeCount = 0;
|
||||||
kevent_t[100] m_changes;
|
kevent_t[100] m_changes;
|
||||||
kevent_t[100] m_events;
|
kevent_t[100] m_events;
|
||||||
|
bool m_forceLevelTriggered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this()
|
this()
|
||||||
|
@ -101,7 +102,7 @@ abstract class KqueueEventLoopBase : PosixEventLoop {
|
||||||
kevent_t ev;
|
kevent_t ev;
|
||||||
ev.ident = fd;
|
ev.ident = fd;
|
||||||
ev.flags = EV_ADD|EV_ENABLE;
|
ev.flags = EV_ADD|EV_ENABLE;
|
||||||
if (edge_triggered) ev.flags |= EV_CLEAR;
|
if (edge_triggered && !m_forceLevelTriggered) ev.flags |= EV_CLEAR;
|
||||||
if (mask & EventMask.read) {
|
if (mask & EventMask.read) {
|
||||||
ev.filter = EVFILT_READ;
|
ev.filter = EVFILT_READ;
|
||||||
putChange(ev);
|
putChange(ev);
|
||||||
|
@ -130,14 +131,14 @@ abstract class KqueueEventLoopBase : PosixEventLoop {
|
||||||
if (changes & EventMask.read) {
|
if (changes & EventMask.read) {
|
||||||
ev.filter = EVFILT_READ;
|
ev.filter = EVFILT_READ;
|
||||||
ev.flags = new_mask & EventMask.read ? EV_ADD : EV_DELETE;
|
ev.flags = new_mask & EventMask.read ? EV_ADD : EV_DELETE;
|
||||||
if (edge_triggered) ev.flags |= EV_CLEAR;
|
if (edge_triggered && !m_forceLevelTriggered) ev.flags |= EV_CLEAR;
|
||||||
putChange(ev);
|
putChange(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changes & EventMask.write) {
|
if (changes & EventMask.write) {
|
||||||
ev.filter = EVFILT_WRITE;
|
ev.filter = EVFILT_WRITE;
|
||||||
ev.flags = new_mask & EventMask.write ? EV_ADD : EV_DELETE;
|
ev.flags = new_mask & EventMask.write ? EV_ADD : EV_DELETE;
|
||||||
if (edge_triggered) ev.flags |= EV_CLEAR;
|
if (edge_triggered && !m_forceLevelTriggered) ev.flags |= EV_CLEAR;
|
||||||
putChange(ev);
|
putChange(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue