diff --git a/source/tanya/async/event/iocp.d b/source/tanya/async/event/iocp.d index b6522d9..ff2b4c4 100644 --- a/source/tanya/async/event/iocp.d +++ b/source/tanya/async/event/iocp.d @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Copyright: Eugene Wissner 2016. + * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) diff --git a/source/tanya/async/event/selector.d b/source/tanya/async/event/selector.d index 5508cac..0b2143f 100644 --- a/source/tanya/async/event/selector.d +++ b/source/tanya/async/event/selector.d @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Copyright: Eugene Wissner 2016. + * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) @@ -13,6 +13,7 @@ module tanya.async.event.selector; version (Posix): import tanya.async.loop; +import tanya.async.protocol; import tanya.async.transport; import tanya.async.watcher; import tanya.container.buffer; @@ -28,6 +29,8 @@ class SelectorStreamTransport : StreamTransport { private ConnectedSocket socket_; + private Protocol protocol_; + /// Input buffer. package WriteBuffer!ubyte input; @@ -40,22 +43,64 @@ class SelectorStreamTransport : StreamTransport * Params: * loop = Event loop. * socket = Socket. + * protocol = Application protocol. + * + * Precondition: $(D_INLINECODE loop !is null + * && socket !is null + * && protocol !is null) */ - this(SelectorLoop loop, ConnectedSocket socket) @nogc + this(SelectorLoop loop, ConnectedSocket socket, Protocol protocol) @nogc + in + { + assert(loop !is null); + assert(socket !is null); + assert(protocol !is null); + } + body { socket_ = socket; this.loop = loop; + protocol_ = protocol; input = WriteBuffer!ubyte(8192, MmapPool.instance); } /** * Returns: Transport socket. */ - inout(ConnectedSocket) socket() inout pure nothrow @safe @nogc + ConnectedSocket socket() pure nothrow @safe @nogc { return socket_; } + /** + * Returns: Application protocol. + */ + @property Protocol protocol() pure nothrow @safe @nogc + { + return protocol_; + } + + /** + * Switches the protocol. + * + * The protocol is deallocated by the event loop, it should currently be + * allocated with $(D_PSYMBOL MmapPool). + * + * Params: + * protocol = Application protocol. + * + * Precondition: $(D_INLINECODE protocol !is null) + */ + @property void protocol(Protocol protocol) pure nothrow @safe @nogc + in + { + assert(protocol !is null); + } + body + { + protocol_ = protocol; + } + /** * Write some data to the transport. * @@ -224,7 +269,8 @@ abstract class SelectorLoop : Loop } IOWatcher io; - auto transport = MmapPool.instance.make!SelectorStreamTransport(this, client); + auto protocol = connection.protocol; + auto transport = MmapPool.instance.make!SelectorStreamTransport(this, client, protocol); if (connections.length > client.handle) { @@ -236,13 +282,12 @@ abstract class SelectorLoop : Loop } if (io is null) { - io = MmapPool.instance.make!IOWatcher(transport, - connection.protocol); + io = MmapPool.instance.make!IOWatcher(transport, protocol); connections[client.handle] = io; } else { - io(transport, connection.protocol); + io(transport, protocol); } reify(io, EventMask(Event.none), EventMask(Event.read, Event.write)); diff --git a/source/tanya/async/iocp.d b/source/tanya/async/iocp.d index 9730262..0dfcbe8 100644 --- a/source/tanya/async/iocp.d +++ b/source/tanya/async/iocp.d @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Copyright: Eugene Wissner 2016. + * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) diff --git a/source/tanya/async/package.d b/source/tanya/async/package.d index 0c5a743..e9ed007 100644 --- a/source/tanya/async/package.d +++ b/source/tanya/async/package.d @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Copyright: Eugene Wissner 2016. + * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) diff --git a/source/tanya/async/transport.d b/source/tanya/async/transport.d index d72d42d..6e4460c 100644 --- a/source/tanya/async/transport.d +++ b/source/tanya/async/transport.d @@ -3,13 +3,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Copyright: Eugene Wissner 2016. + * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) */ module tanya.async.transport; +import tanya.async.protocol; import tanya.network.socket; /** @@ -45,6 +46,33 @@ interface WriteTransport : Transport */ interface DuplexTransport : ReadTransport, WriteTransport { + /** + * Returns: Application protocol. + * + * Postcondition: $(D_INLINECODE protocol !is null) + */ + @property Protocol protocol() pure nothrow @safe @nogc + out (protocol) + { + assert(protocol !is null); + } + + /** + * Switches the protocol. + * + * The protocol is deallocated by the event loop, it should currently be + * allocated with $(D_PSYMBOL MmapPool). + * + * Params: + * protocol = Application protocol. + * + * Precondition: $(D_INLINECODE protocol !is null) + */ + @property void protocol(Protocol protocol) pure nothrow @safe @nogc + in + { + assert(protocol !is null); + } } /** @@ -52,7 +80,7 @@ interface DuplexTransport : ReadTransport, WriteTransport */ interface SocketTransport : Transport { - @property inout(Socket) socket() inout pure nothrow @safe @nogc; + @property Socket socket() pure nothrow @safe @nogc; } /** diff --git a/source/tanya/async/watcher.d b/source/tanya/async/watcher.d index 44b7a1d..de23aa1 100644 --- a/source/tanya/async/watcher.d +++ b/source/tanya/async/watcher.d @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * Copyright: Eugene Wissner 2016. + * Copyright: Eugene Wissner 2016-2017. * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * Mozilla Public License, v. 2.0). * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) @@ -90,7 +90,7 @@ class ConnectionWatcher : Watcher /** * Returns: Socket. */ - @property inout(Socket) socket() inout pure nothrow @nogc + @property Socket socket() pure nothrow @nogc { return socket_; } @@ -222,7 +222,7 @@ class IOWatcher : ConnectionWatcher /** * Returns: Socket. */ - override @property inout(Socket) socket() inout pure nothrow @nogc + override @property Socket socket() pure nothrow @nogc { return transport.socket; } diff --git a/source/tanya/container/string.d b/source/tanya/container/string.d new file mode 100644 index 0000000..05f9e70 --- /dev/null +++ b/source/tanya/container/string.d @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Copyright: Eugene Wissner 2016-2017. + * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, + * Mozilla Public License, v. 2.0). + * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) + */ +module tanya.container.string; + +import core.exception; +import core.stdc.string; +import tanya.memory; + +/** + * UTF-8 string. + */ +struct String +{ + private char[] data; + private size_t length_; + + invariant + { + assert(length_ <= data.length); + } + + /// Ditto. + this(const(char)[] str, shared Allocator allocator = defaultAllocator) + nothrow @trusted @nogc + { + this(allocator); + + data = cast(char[]) allocator.allocate(str.length); + if (str.length > 0 && data is null) + { + onOutOfMemoryErrorNoGC(); + } + memcpy(data.ptr, str.ptr, str.length); + } + + /// Ditto. + this(const(wchar)[] str, shared Allocator allocator = defaultAllocator) + nothrow @trusted @nogc + { + this(allocator); + + } + + /// Ditto. + this(const(dchar)[] str, shared Allocator allocator = defaultAllocator) + nothrow @trusted @nogc + { + this(allocator); + + } + + /// Ditto. + this(shared Allocator allocator) pure nothrow @safe @nogc + in + { + assert(allocator !is null); + } + body + { + allocator_ = allocator; + } + + ~this() nothrow @trusted @nogc + { + allocator.deallocate(data); + } + + mixin DefaultAllocator; +}