diff --git a/source/eventcore/drivers/epoll.d b/source/eventcore/drivers/epoll.d index 70d59f7..e054c8a 100644 --- a/source/eventcore/drivers/epoll.d +++ b/source/eventcore/drivers/epoll.d @@ -75,13 +75,13 @@ final class EpollEventLoop : PosixEventLoop { () @trusted { epoll_ctl(m_epoll, EPOLL_CTL_ADD, fd, &ev); } (); } - override void unregisterFD(FD fd) + override void unregisterFD(FD fd, EventMask mask) { debug (EventCoreEpollDebug) print("Epoll unregister FD %s", fd); () @trusted { epoll_ctl(m_epoll, EPOLL_CTL_DEL, fd, null); } (); } - override void updateFD(FD fd, EventMask mask) + override void updateFD(FD fd, EventMask old_mask, EventMask mask) { debug (EventCoreEpollDebug) print("Epoll update FD %s: %s", fd, mask); epoll_event ev; diff --git a/source/eventcore/drivers/kqueue.d b/source/eventcore/drivers/kqueue.d index d44e331..9d77c9c 100644 --- a/source/eventcore/drivers/kqueue.d +++ b/source/eventcore/drivers/kqueue.d @@ -37,8 +37,9 @@ final class KqueueEventLoop : PosixEventLoop { } this() - @safe nothrow @nogc { + @safe nothrow { m_queue = () @trusted { return kqueue(); } (); + m_events.length = 100; assert(m_queue >= 0, "Failed to create kqueue."); } @@ -58,9 +59,11 @@ final class KqueueEventLoop : PosixEventLoop { m_changes.length = 0; m_changes.assumeSafeAppend(); + print("kevent returned %s", ret); + if (ret > 0) { foreach (ref evt; m_events[0 .. ret]) { - //print("event %s %s", evt.data.fd, evt.events); + print("event %s %s", evt.ident, evt.filter, evt.flags); assert(evt.ident <= uint.max); auto fd = cast(FD)cast(int)evt.ident; if (evt.flags & (EV_EOF|EV_ERROR)) @@ -89,13 +92,18 @@ final class KqueueEventLoop : PosixEventLoop { kevent_t ev; ev.ident = fd; ev.flags = EV_ADD|EV_CLEAR|EV_ENABLE; - if (mask & EventMask.read) ev.filter |= EVFILT_READ; - if (mask & EventMask.write) ev.filter |= EVFILT_WRITE; + if (mask & EventMask.read) { + ev.filter = EVFILT_READ; + m_changes ~= ev; + } + if (mask & EventMask.write) { + ev.filter = EVFILT_WRITE; + m_changes ~= ev; + } //if (mask & EventMask.status) ev.events |= EPOLLERR|EPOLLRDHUP; - m_changes ~= ev; } - override void unregisterFD(FD fd) + override void unregisterFD(FD fd, EventMask mask) { kevent_t ev; ev.ident = fd; @@ -103,15 +111,24 @@ final class KqueueEventLoop : PosixEventLoop { m_changes ~= ev; } - override void updateFD(FD fd, EventMask mask) + override void updateFD(FD fd, EventMask old_mask, EventMask new_mask) { //print("update %s %s", fd, mask); kevent_t ev; - ev.filter = 0; - ev.flags |= EV_CLEAR; - if (mask & EventMask.read) ev.filter |= EVFILT_READ; - if (mask & EventMask.write) ev.filter |= EVFILT_WRITE; + auto changes = old_mask ^ new_mask; + + if (changes & EventMask.read) { + ev.filter = EVFILT_READ; + ev.flags = EV_CLEAR | (new_mask & EventMask.read ? EV_ADD : EV_DELETE); + m_changes ~= ev; + } + + if (changes & EventMask.write) { + ev.filter = EVFILT_WRITE; + ev.flags = EV_CLEAR | (new_mask & EventMask.write ? EV_ADD : EV_DELETE); + m_changes ~= ev; + } + //if (mask & EventMask.status) ev.events |= EPOLLERR|EPOLLRDHUP; - m_changes ~= ev; } } diff --git a/source/eventcore/drivers/posix.d b/source/eventcore/drivers/posix.d index a63edb5..40830be 100644 --- a/source/eventcore/drivers/posix.d +++ b/source/eventcore/drivers/posix.d @@ -66,6 +66,7 @@ final class PosixEventDriver(Loop : PosixEventLoop) : EventDriver { else alias DNSDriver = EventDriverDNS_GAI!(EventsDriver, SignalsDriver); alias FileDriver = ThreadedFileEventDriver!EventsDriver; version (linux) alias WatcherDriver = InotifyEventDriverWatchers!Loop; + else version (OSX) alias WatcherDriver = FSEventsEventDriverWatchers!Loop; else alias WatcherDriver = PosixEventDriverWatchers!Loop; Loop m_loop; @@ -265,7 +266,7 @@ final class PosixEventDriverSockets(Loop : PosixEventLoop) : EventDriverSockets m_loop.setNotifyCallback!(EventType.write)(sock, &onConnect); } else { m_loop.clearFD(sock); - m_loop.unregisterFD(sock); + m_loop.unregisterFD(sock, EventMask.read|EventMask.write|EventMask.status); invalidateSocket(); on_connect(sock, ConnectStatus.unknownError); return sock; @@ -416,7 +417,7 @@ final class PosixEventDriverSockets(Loop : PosixEventLoop) : EventDriverSockets } } - if (ret == 0) { + if (ret == 0 && buffer.length > 0) { print("disconnect"); on_read_finish(socket, IOStatus.disconnected, 0); return; @@ -428,7 +429,7 @@ final class PosixEventDriverSockets(Loop : PosixEventLoop) : EventDriverSockets return; } - if (ret > 0) { + if (ret > 0 || buffer.length == 0) { buffer = buffer[ret .. $]; if (mode != IOMode.all || buffer.length == 0) { on_read_finish(socket, IOStatus.ok, ret); @@ -864,7 +865,7 @@ final class PosixEventDriverSockets(Loop : PosixEventLoop) : EventDriverSockets { assert(m_loop.m_fds[fd].common.refCount > 0, "Releasing reference to unreferenced socket FD."); if (--m_loop.m_fds[fd].common.refCount == 0) { - m_loop.unregisterFD(fd); + m_loop.unregisterFD(fd, EventMask.read|EventMask.write|EventMask.status); m_loop.clearFD(fd); closeSocket(fd); return false; @@ -1301,7 +1302,7 @@ final class PosixEventDriverEvents(Loop : PosixEventLoop, Sockets : EventDriverS version (linux) { if (--getRC(descriptor) == 0) { destroy(); - m_loop.unregisterFD(descriptor); + m_loop.unregisterFD(descriptor, EventMask.read); m_loop.clearFD(descriptor); close(descriptor); return false; @@ -1377,7 +1378,7 @@ final class SignalFDEventDriverSignals(Loop : PosixEventLoop) : EventDriverSigna FD fd = cast(FD)descriptor; assert(m_loop.m_fds[fd].common.refCount > 0, "Releasing reference to unreferenced event FD."); if (--m_loop.m_fds[fd].common.refCount == 0) { - m_loop.unregisterFD(fd); + m_loop.unregisterFD(fd, EventMask.read); m_loop.clearFD(fd); close(fd); return false; @@ -1479,7 +1480,7 @@ final class InotifyEventDriverWatchers(Loop : PosixEventLoop) : EventDriverWatch FD fd = cast(FD)descriptor; assert(m_loop.m_fds[fd].common.refCount > 0, "Releasing reference to unreferenced event FD."); if (--m_loop.m_fds[fd].common.refCount == 0) { - m_loop.unregisterFD(fd); + m_loop.unregisterFD(fd, EventMask.read); m_loop.clearFD(fd); m_watches.remove(fd); /*errnoEnforce(*/close(fd)/* == 0)*/; @@ -1544,6 +1545,36 @@ final class InotifyEventDriverWatchers(Loop : PosixEventLoop) : EventDriverWatch } } +version (OSX) +final class FSEventsEventDriverWatchers(Loop : PosixEventLoop) : EventDriverWatchers { +@safe: /*@nogc:*/ nothrow: + private Loop m_loop; + + this(Loop loop) { m_loop = loop; } + + final override WatcherID watchDirectory(string path, bool recursive, FileChangesCallback on_change) + { + /*FSEventStreamCreate + FSEventStreamScheduleWithRunLoop + FSEventStreamStart*/ + assert(false, "TODO!"); + } + + final override void addRef(WatcherID descriptor) + { + assert(false, "TODO!"); + } + + final override bool releaseRef(WatcherID descriptor) + { + /*FSEventStreamStop + FSEventStreamUnscheduleFromRunLoop + FSEventStreamInvalidate + FSEventStreamRelease*/ + assert(false, "TODO!"); + } +} + final class PosixEventDriverWatchers(Loop : PosixEventLoop) : EventDriverWatchers { @safe: /*@nogc:*/ nothrow: private Loop m_loop; @@ -1585,9 +1616,9 @@ package class PosixEventLoop { /// Registers the FD for general notification reception. protected abstract void registerFD(FD fd, EventMask mask); /// Unregisters the FD for general notification reception. - protected abstract void unregisterFD(FD fd); + protected abstract void unregisterFD(FD fd, EventMask mask); /// Updates the event mask to use for listening for notifications. - protected abstract void updateFD(FD fd, EventMask mask); + protected abstract void updateFD(FD fd, EventMask old_mask, EventMask new_mask); final protected void notify(EventType evt)(FD fd) { diff --git a/source/eventcore/drivers/select.d b/source/eventcore/drivers/select.d index a36ba2b..93602f2 100644 --- a/source/eventcore/drivers/select.d +++ b/source/eventcore/drivers/select.d @@ -76,11 +76,11 @@ final class SelectEventLoop : PosixEventLoop { { } - override void unregisterFD(FD fd) + override void unregisterFD(FD fd, EventMask mask) { } - override void updateFD(FD fd, EventMask mask) + override void updateFD(FD fd, EventMask old_mask, EventMask mask) { } }