diff --git a/source/tanya/async/event/epoll.d b/source/tanya/async/event/epoll.d index 9f16c99..d582366 100644 --- a/source/tanya/async/event/epoll.d +++ b/source/tanya/async/event/epoll.d @@ -18,6 +18,7 @@ import tanya.async.event.selector; import tanya.async.loop; import tanya.async.transport; import tanya.async.watcher; +import tanya.container.vector; import tanya.memory; import tanya.memory.mmappool; import tanya.network.socket; @@ -36,7 +37,7 @@ extern (C) nothrow @nogc class EpollLoop : SelectorLoop { protected int fd; - private epoll_event[] events; + private Vector!epoll_event events; /** * Initializes the loop. @@ -48,15 +49,14 @@ class EpollLoop : SelectorLoop throw MmapPool.instance.make!BadLoopException("epoll initialization failed"); } super(); - MmapPool.instance.resizeArray(events, maxEvents); + events = Vector!epoll_event(maxEvents, MmapPool.instance); } /** - * Free loop internals. + * Frees loop internals. */ ~this() @nogc { - MmapPool.instance.dispose(events); close(fd); } @@ -97,8 +97,8 @@ class EpollLoop : SelectorLoop ev.data.fd = watcher.socket.handle; ev.events = (events & (Event.read | Event.accept) ? EPOLLIN | EPOLLPRI : 0) - | (events & Event.write ? EPOLLOUT : 0) - | EPOLLET; + | (events & Event.write ? EPOLLOUT : 0) + | EPOLLET; return epoll_ctl(fd, op, watcher.socket.handle, &ev) == 0; } @@ -110,7 +110,7 @@ class EpollLoop : SelectorLoop { // Don't block immutable timeout = cast(immutable int) blockTime.total!"msecs"; - auto eventCount = epoll_wait(fd, events.ptr, maxEvents, timeout); + auto eventCount = epoll_wait(fd, events.data.ptr, maxEvents, timeout); if (eventCount < 0) { diff --git a/source/tanya/async/event/kqueue.d b/source/tanya/async/event/kqueue.d index 6e58178..47bac9e 100644 --- a/source/tanya/async/event/kqueue.d +++ b/source/tanya/async/event/kqueue.d @@ -41,8 +41,19 @@ else version (DragonFlyBSD) version (MacBSD): -import core.stdc.stdint; // intptr_t, uintptr_t +import core.stdc.errno; import core.sys.posix.time; // timespec +import core.sys.posix.unistd; +import core.time; +import std.algorithm.comparison; +import tanya.async.event.selector; +import tanya.async.loop; +import tanya.async.transport; +import tanya.async.watcher; +import tanya.container.vector; +import tanya.memory; +import tanya.memory.mmappool; +import tanya.network.socket; void EV_SET(kevent_t* kevp, typeof(kevent_t.tupleof) args) pure nothrow @nogc { @@ -102,24 +113,11 @@ extern(C) int kevent(int kq, const kevent_t *changelist, int nchanges, kevent_t *eventlist, int nevents, const timespec *timeout) nothrow @nogc; -import tanya.async.event.selector; -import tanya.async.loop; -import tanya.async.transport; -import tanya.async.watcher; -import tanya.memory; -import tanya.memory.mmappool; -import tanya.network.socket; -import core.stdc.errno; -import core.sys.posix.unistd; -import core.sys.posix.sys.time; -import core.time; -import std.algorithm.comparison; - class KqueueLoop : SelectorLoop { protected int fd; - private kevent_t[] events; - private kevent_t[] changes; + private Vector!kevent_t events; + private Vector!kevent_t changes; private size_t changeCount; /** @@ -138,19 +136,18 @@ class KqueueLoop : SelectorLoop if ((fd = kqueue()) == -1) { - throw MmapPool.instance.make!BadLoopException("epoll initialization failed"); + throw make!BadLoopException(defaultAllocator, + "kqueue initialization failed"); } - MmapPool.instance.resizeArray(events, 64); - MmapPool.instance.resizeArray(changes, 64); + events = Vector!kevent_t(64, MmapPool.instance); + changes = Vector!kevent_t(64, MmapPool.instance); } /** - * Free loop internals. + * Frees loop internals. */ ~this() @nogc { - MmapPool.instance.dispose(events); - MmapPool.instance.dispose(changes); close(fd); } @@ -158,7 +155,7 @@ class KqueueLoop : SelectorLoop { if (changes.length <= changeCount) { - MmapPool.instance.resizeArray(changes, changeCount + maxEvents); + changes.length = changeCount + maxEvents; } EV_SET(&changes[changeCount], cast(ulong) socket, @@ -216,10 +213,15 @@ class KqueueLoop : SelectorLoop if (changeCount > maxEvents) { - MmapPool.instance.resizeArray(events, changes.length); + events.length = changes.length; } - auto eventCount = kevent(fd, changes.ptr, cast(int) changeCount, events.ptr, maxEvents, &ts); + auto eventCount = kevent(fd, + changes.data.ptr, + cast(int) changeCount, + events.data.ptr, + maxEvents, + &ts); changeCount = 0; if (eventCount < 0) diff --git a/source/tanya/async/event/selector.d b/source/tanya/async/event/selector.d index 91c0c69..5508cac 100644 --- a/source/tanya/async/event/selector.d +++ b/source/tanya/async/event/selector.d @@ -16,11 +16,10 @@ import tanya.async.loop; import tanya.async.transport; import tanya.async.watcher; import tanya.container.buffer; +import tanya.container.vector; import tanya.memory; import tanya.memory.mmappool; import tanya.network.socket; -import core.sys.posix.netinet.in_; -import core.stdc.errno; /** * Transport for stream sockets. @@ -103,12 +102,12 @@ class SelectorStreamTransport : StreamTransport abstract class SelectorLoop : Loop { /// Pending connections. - protected ConnectionWatcher[] connections; + protected Vector!ConnectionWatcher connections; this() @nogc { super(); - MmapPool.instance.resizeArray(connections, maxEvents); + connections = Vector!ConnectionWatcher(maxEvents, MmapPool.instance); } ~this() @nogc @@ -124,7 +123,6 @@ abstract class SelectorLoop : Loop connection = null; } } - MmapPool.instance.dispose(connections); } /** @@ -188,7 +186,7 @@ abstract class SelectorLoop : Loop if (connections.length <= watcher.socket) { - MmapPool.instance.resizeArray(connections, watcher.socket.handle + maxEvents / 2); + connections.length = watcher.socket.handle + maxEvents / 2; } connections[watcher.socket.handle] = watcher; @@ -234,7 +232,7 @@ abstract class SelectorLoop : Loop } else { - MmapPool.instance.resizeArray(connections, client.handle + maxEvents / 2); + connections.length = client.handle + maxEvents / 2; } if (io is null) { diff --git a/source/tanya/container/vector.d b/source/tanya/container/vector.d index 0a650e5..868cc40 100644 --- a/source/tanya/container/vector.d +++ b/source/tanya/container/vector.d @@ -1083,7 +1083,7 @@ struct Vector(T) * Params: * dg = $(D_KEYWORD foreach) body. */ - int opApply(scope int delegate(ref T) dg) + int opApply(scope int delegate(ref T) @nogc dg) { T* end = vector + length_ - 1; for (T* begin = vector; begin != end; ++begin) @@ -1098,7 +1098,7 @@ struct Vector(T) } /// Ditto. - int opApply(scope int delegate(ref size_t i, ref T) dg) + int opApply(scope int delegate(ref size_t i, ref T) @nogc dg) { for (size_t i = 0; i < length_; ++i) { @@ -1395,6 +1395,19 @@ struct Vector(T) assert(v2[1] == 3); } + /** + * Returns an array used internally by the vector to store its owned elements. + * The length of the returned array may differ from the size of the allocated + * memory for the vector: the array contains only initialized elements, but + * not the reserved memory. + * + * Returns: The array with elements of this vector. + */ + inout(T[]) data() inout + { + return vector[0 .. length]; + } + mixin DefaultAllocator; }