Let Transport extend IOWatcher

This commit is contained in:
2017-02-09 15:04:26 +01:00
committed by Eugene Wissner
parent 0e91ea6786
commit f9023cf0ab
5 changed files with 53 additions and 104 deletions

View File

@ -123,30 +123,27 @@ class EpollLoop : SelectorLoop
for (auto i = 0; i < eventCount; ++i)
{
auto io = cast(IOWatcher) connections[events[i].data.fd];
auto transport = cast(SelectorStreamTransport) connections[events[i].data.fd];
if (io is null)
if (transport is null)
{
acceptConnections(connections[events[i].data.fd]);
}
else if (events[i].events & EPOLLERR)
{
kill(io, null);
kill(transport, null);
continue;
}
else if (events[i].events & (EPOLLIN | EPOLLPRI | EPOLLHUP))
{
auto transport = cast(SelectorStreamTransport) io.transport;
assert(transport !is null);
SocketException exception;
try
{
ptrdiff_t received;
do
{
received = transport.socket.receive(io.output[]);
io.output += received;
received = transport.socket.receive(transport.output[]);
transport.output += received;
}
while (received);
}
@ -156,19 +153,16 @@ class EpollLoop : SelectorLoop
}
if (transport.socket.disconnected)
{
kill(io, exception);
kill(transport, exception);
continue;
}
else if (io.output.length)
else if (transport.output.length)
{
pendings.enqueue(io);
pendings.enqueue(transport);
}
}
if (events[i].events & EPOLLOUT)
{
auto transport = cast(SelectorStreamTransport) io.transport;
assert(transport !is null);
transport.writeReady = true;
if (transport.input.length)
{

View File

@ -259,7 +259,7 @@ class IOCPLoop : Loop
auto transport = MmapPool.instance.make!IOCPStreamTransport(socket, protocol);
auto io = MmapPool.instance.make!IOWatcher(transport, socket, protocol);
connection.incoming.enqueue(io);
connection.incoming.enqueue(transport);
reify(io, EventMask(Event.none), EventMask(Event.read, Event.write));

View File

@ -25,12 +25,8 @@ import tanya.network.socket;
/**
* Transport for stream sockets.
*/
class SelectorStreamTransport : StreamTransport
class SelectorStreamTransport : IOWatcher, StreamTransport
{
private ConnectedSocket socket_;
private Protocol protocol_;
/// Input buffer.
package WriteBuffer!ubyte input;
@ -43,41 +39,38 @@ class SelectorStreamTransport : StreamTransport
* Params:
* loop = Event loop.
* socket = Socket.
* protocol = Application protocol.
*
* Precondition: $(D_INLINECODE loop !is null
* && socket !is null
* && protocol !is null)
* Precondition: $(D_INLINECODE loop !is null && socket !is null)
*/
this(SelectorLoop loop, ConnectedSocket socket, Protocol protocol) @nogc
this(SelectorLoop loop, ConnectedSocket socket) @nogc
in
{
assert(loop !is null);
assert(socket !is null);
assert(protocol !is null);
}
body
{
socket_ = socket;
super(socket);
this.loop = loop;
protocol_ = protocol;
input = WriteBuffer!ubyte(8192, MmapPool.instance);
}
/**
* Returns: Socket.
*/
ConnectedSocket socket() pure nothrow @safe @nogc
override @property ConnectedSocket socket() pure nothrow @safe @nogc
{
return socket_;
return cast(ConnectedSocket) socket_;
}
/**
* Returns: Application protocol.
*/
@property Protocol protocol() pure nothrow @safe @nogc
private @property void socket(ConnectedSocket socket) pure nothrow @safe @nogc
in
{
return protocol_;
assert(socket !is null);
}
body
{
socket_ = socket;
}
/**
@ -268,30 +261,28 @@ abstract class SelectorLoop : Loop
break;
}
IOWatcher io;
auto protocol = connection.protocol;
auto transport = MmapPool.instance.make!SelectorStreamTransport(this, client, protocol);
SelectorStreamTransport transport;
if (connections.length > client.handle)
{
io = cast(IOWatcher) connections[client.handle];
transport = cast(SelectorStreamTransport) connections[client.handle];
}
else
{
connections.length = client.handle + maxEvents / 2;
}
if (io is null)
if (transport is null)
{
io = MmapPool.instance.make!IOWatcher(transport, client, protocol);
connections[client.handle] = io;
transport = MmapPool.instance.make!SelectorStreamTransport(this, client);
connections[client.handle] = transport;
}
else
{
io(transport, client, protocol);
transport.socket = client;
}
reify(io, EventMask(Event.none), EventMask(Event.read, Event.write));
connection.incoming.enqueue(io);
reify(transport, EventMask(Event.none), EventMask(Event.read, Event.write));
connection.incoming.enqueue(transport);
}
if (!connection.incoming.empty)