Make the kqueue event driver compile on macOS (doesn't work yet).
This commit is contained in:
parent
2e09dcce41
commit
c9c6d73f5e
|
@ -7,9 +7,9 @@
|
||||||
module eventcore.drivers.kqueue;
|
module eventcore.drivers.kqueue;
|
||||||
@safe: /*@nogc:*/ nothrow:
|
@safe: /*@nogc:*/ nothrow:
|
||||||
|
|
||||||
/*version (FreeBSD) enum have_kqueue = true;
|
version (FreeBSD) enum have_kqueue = true;
|
||||||
else version (OSX) enum have_kqueue = true;
|
else version (OSX) enum have_kqueue = true;
|
||||||
else*/ enum have_kqueue = false;
|
else enum have_kqueue = false;
|
||||||
|
|
||||||
static if (have_kqueue):
|
static if (have_kqueue):
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ public import eventcore.drivers.posix;
|
||||||
import eventcore.internal.utils;
|
import eventcore.internal.utils;
|
||||||
|
|
||||||
import core.time : Duration;
|
import core.time : Duration;
|
||||||
import core.sys.posix.sys.time : timespec;
|
import core.sys.posix.sys.time : timespec, time_t;
|
||||||
|
|
||||||
version (OSX) import core.sys.darwin.sys.event;
|
version (OSX) import core.sys.darwin.sys.event;
|
||||||
else version (FreeBSD) import core.sys.freebsd.sys.event;
|
else version (FreeBSD) import core.sys.freebsd.sys.event;
|
||||||
|
@ -32,14 +32,14 @@ alias KqueueEventDriver = PosixEventDriver!KqueueEventLoop;
|
||||||
final class KqueueEventLoop : PosixEventLoop {
|
final class KqueueEventLoop : PosixEventLoop {
|
||||||
private {
|
private {
|
||||||
int m_queue;
|
int m_queue;
|
||||||
kevent[] m_fds;
|
kevent_t[] m_changes;
|
||||||
kevent[] m_events;
|
kevent_t[] m_events;
|
||||||
}
|
}
|
||||||
|
|
||||||
this()
|
this()
|
||||||
{
|
@safe nothrow @nogc {
|
||||||
m_queue = kqueue();
|
m_queue = () @trusted { return kqueue(); } ();
|
||||||
enforce(m_queue >= 0, "Failed to create kqueue.");
|
assert(m_queue >= 0, "Failed to create kqueue.");
|
||||||
}
|
}
|
||||||
|
|
||||||
override bool doProcessEvents(Duration timeout)
|
override bool doProcessEvents(Duration timeout)
|
||||||
|
@ -50,20 +50,26 @@ final class KqueueEventLoop : PosixEventLoop {
|
||||||
//print("wait %s", m_events.length);
|
//print("wait %s", m_events.length);
|
||||||
timespec ts;
|
timespec ts;
|
||||||
long secs, hnsecs;
|
long secs, hnsecs;
|
||||||
dur.split!("seconds", "hnsecs")(secs, hnsecs);
|
timeout.split!("seconds", "hnsecs")(secs, hnsecs);
|
||||||
ts.tv_sec = cast(time_t)secs;
|
ts.tv_sec = cast(time_t)secs;
|
||||||
ts.tv_nsec = hnsecs * 100;
|
ts.tv_nsec = hnsecs * 100;
|
||||||
|
|
||||||
auto ret = kevent(m_queue, m_fds, m_fds.length, m_events, m_events.length, timeout == Duration.max ? null : &ts);
|
auto ret = kevent(m_queue, m_changes.ptr, cast(int)m_changes.length, m_events.ptr, cast(int)m_events.length, timeout == Duration.max ? null : &ts);
|
||||||
|
m_changes.length = 0;
|
||||||
|
m_changes.assumeSafeAppend();
|
||||||
|
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
foreach (ref evt; m_events[0 .. ret]) {
|
foreach (ref evt; m_events[0 .. ret]) {
|
||||||
//print("event %s %s", evt.data.fd, evt.events);
|
//print("event %s %s", evt.data.fd, evt.events);
|
||||||
auto fd = cast(FD)evt.ident;
|
assert(evt.ident <= uint.max);
|
||||||
if (evt.flags & EV_READ) notify!(EventType.read)(fd);
|
auto fd = cast(FD)cast(int)evt.ident;
|
||||||
if (evt.flags & EV_WRITE) notify!(EventType.write)(fd);
|
if (evt.flags & (EV_EOF|EV_ERROR))
|
||||||
if (evt.flags & EV_ERROR) notify!(EventType.status)(fd);
|
notify!(EventType.status)(fd);
|
||||||
else if (evt.flags & EV_EOF) notify!(EventType.status)(fd);
|
switch (evt.filter) {
|
||||||
|
default: break;
|
||||||
|
case EVFILT_READ: notify!(EventType.read)(fd); break;
|
||||||
|
case EVFILT_WRITE: notify!(EventType.write)(fd); break;
|
||||||
|
}
|
||||||
// EV_SIGNAL, EV_TIMEOUT
|
// EV_SIGNAL, EV_TIMEOUT
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -80,30 +86,32 @@ final class KqueueEventLoop : PosixEventLoop {
|
||||||
override void registerFD(FD fd, EventMask mask)
|
override void registerFD(FD fd, EventMask mask)
|
||||||
{
|
{
|
||||||
//print("register %s %s", fd, mask);
|
//print("register %s %s", fd, mask);
|
||||||
auto idx = allocSlot(fd);
|
kevent_t ev;
|
||||||
kevent* ev = &m_events[idx];
|
|
||||||
ev.ident = fd;
|
ev.ident = fd;
|
||||||
ev.flags = EV_ADD|EV_ET|EV_ENABLE;
|
ev.flags = EV_ADD|EV_CLEAR|EV_ENABLE;
|
||||||
if (mask & EventMask.read) ev.filter |= EVFILT_READ;
|
if (mask & EventMask.read) ev.filter |= EVFILT_READ;
|
||||||
if (mask & EventMask.write) ev.filter |= EVFILT_WRITE;
|
if (mask & EventMask.write) ev.filter |= EVFILT_WRITE;
|
||||||
if (mask & EventMask.status) ev.events |= EPOLLERR|EPOLLRDHUP;
|
//if (mask & EventMask.status) ev.events |= EPOLLERR|EPOLLRDHUP;
|
||||||
|
m_changes ~= ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
override void unregisterFD(FD fd)
|
override void unregisterFD(FD fd)
|
||||||
{
|
{
|
||||||
auto idx = m_eventMap[fd];
|
kevent_t ev;
|
||||||
m_events[idx].flags = EV_REMOVE;
|
ev.ident = fd;
|
||||||
|
ev.flags = EV_DELETE;
|
||||||
|
m_changes ~= ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
override void updateFD(FD fd, EventMask mask)
|
override void updateFD(FD fd, EventMask mask)
|
||||||
{
|
{
|
||||||
//print("update %s %s", fd, mask);
|
//print("update %s %s", fd, mask);
|
||||||
auto idx = m_eventMap[fd];
|
kevent_t ev;
|
||||||
epoll_event* ev = &m_events[idx];
|
|
||||||
ev.filter = 0;
|
ev.filter = 0;
|
||||||
ev.events |= EPOLLET;
|
ev.flags |= EV_CLEAR;
|
||||||
if (mask & EventMask.read) ev.filter |= EVFILT_READ;
|
if (mask & EventMask.read) ev.filter |= EVFILT_READ;
|
||||||
if (mask & EventMask.write) ev.filter |= EVFILT_WRITE;
|
if (mask & EventMask.write) ev.filter |= EVFILT_WRITE;
|
||||||
if (mask & EventMask.status) ev.events |= EPOLLERR|EPOLLRDHUP;
|
//if (mask & EventMask.status) ev.events |= EPOLLERR|EPOLLRDHUP;
|
||||||
|
m_changes ~= ev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue