summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-01-12 10:17:12 +0100
committerEugen Wissner <belka@caraus.de>2017-01-12 10:17:12 +0100
commitcb6cc6511374798d13d3a191f2a97dfa293ad9bd (patch)
tree0259d60f37ed5fea7187331d82d5bdeb1ec023d3
parent4de42ca227b667efcd113244e8b653d01dddfb75 (diff)
downloadtanya-cb6cc6511374798d13d3a191f2a97dfa293ad9bd.tar.gz
async: Switch to the internal use of the vector instead of built-in arrays
-rw-r--r--source/tanya/async/event/epoll.d14
-rw-r--r--source/tanya/async/event/kqueue.d52
-rw-r--r--source/tanya/async/event/selector.d12
-rw-r--r--source/tanya/container/vector.d17
4 files changed, 54 insertions, 41 deletions
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;
}