summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2017-02-08 20:04:05 +0100
committerEugen Wissner <belka@caraus.de>2017-02-08 20:04:05 +0100
commit48a49c2a2d8b246b75fb9e2114f65a3d51f96239 (patch)
tree7b5ccfd8f3286484731a73383f7c4d91544c7f2b
parent43c28b749d2fec76704cb0b6d37d5b2555bf0f2a (diff)
downloadtanya-48a49c2a2d8b246b75fb9e2114f65a3d51f96239.tar.gz
Add protocol property to the transport
Transport should be protocol aware because it should be possible to switch the protocol if the operation is supported, for example for upgrading HTTP to web sockets or HTTP 1.1 to HTTP/2.
-rw-r--r--source/tanya/async/event/iocp.d2
-rw-r--r--source/tanya/async/event/selector.d59
-rw-r--r--source/tanya/async/iocp.d2
-rw-r--r--source/tanya/async/package.d2
-rw-r--r--source/tanya/async/transport.d32
-rw-r--r--source/tanya/async/watcher.d6
-rw-r--r--source/tanya/container/string.d77
7 files changed, 165 insertions, 15 deletions
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,23 +43,65 @@ 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.
*
* Params:
@@ -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;
+}