Replace class Queue with the struct Queue

This commit is contained in:
Eugen Wissner 2016-12-13 10:56:29 +01:00
parent 711855474c
commit ab9f96e0c7
10 changed files with 141 additions and 113 deletions

View File

@ -26,6 +26,13 @@ import core.sys.posix.unistd;
import core.time; import core.time;
import std.algorithm.comparison; import std.algorithm.comparison;
extern (C) nothrow @nogc
{
int epoll_create1(int flags);
int epoll_ctl (int epfd, int op, int fd, epoll_event *event);
int epoll_wait (int epfd, epoll_event *events, int maxevents, int timeout);
}
class EpollLoop : SelectorLoop class EpollLoop : SelectorLoop
{ {
protected int fd; protected int fd;
@ -34,7 +41,7 @@ class EpollLoop : SelectorLoop
/** /**
* Initializes the loop. * Initializes the loop.
*/ */
this() this() @nogc
{ {
if ((fd = epoll_create1(EPOLL_CLOEXEC)) < 0) if ((fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
{ {
@ -47,7 +54,7 @@ class EpollLoop : SelectorLoop
/** /**
* Free loop internals. * Free loop internals.
*/ */
~this() ~this() @nogc
{ {
MmapPool.instance.dispose(events); MmapPool.instance.dispose(events);
close(fd); close(fd);
@ -63,7 +70,9 @@ class EpollLoop : SelectorLoop
* *
* Returns: $(D_KEYWORD true) if the operation was successful. * Returns: $(D_KEYWORD true) if the operation was successful.
*/ */
protected override bool reify(ConnectionWatcher watcher, EventMask oldEvents, EventMask events) protected override bool reify(ConnectionWatcher watcher,
EventMask oldEvents,
EventMask events) @nogc
in in
{ {
assert(watcher !is null); assert(watcher !is null);
@ -97,7 +106,7 @@ class EpollLoop : SelectorLoop
/** /**
* Does the actual polling. * Does the actual polling.
*/ */
protected override void poll() protected override void poll() @nogc
{ {
// Don't block // Don't block
immutable timeout = cast(immutable int) blockTime.total!"msecs"; immutable timeout = cast(immutable int) blockTime.total!"msecs";

View File

@ -37,7 +37,7 @@ class IOCPStreamTransport : StreamTransport
* Params: * Params:
* socket = Socket. * socket = Socket.
*/ */
this(OverlappedConnectedSocket socket) this(OverlappedConnectedSocket socket) @nogc
in in
{ {
assert(socket !is null); assert(socket !is null);
@ -53,7 +53,8 @@ class IOCPStreamTransport : StreamTransport
MmapPool.instance.dispose(input); MmapPool.instance.dispose(input);
} }
@property inout(OverlappedConnectedSocket) socket() inout pure nothrow @safe @nogc @property inout(OverlappedConnectedSocket) socket()
inout pure nothrow @safe @nogc
{ {
return socket_; return socket_;
} }
@ -64,7 +65,7 @@ class IOCPStreamTransport : StreamTransport
* Params: * Params:
* data = Data to send. * data = Data to send.
*/ */
void write(ubyte[] data) void write(ubyte[] data) @nogc
{ {
immutable empty = input.length == 0; immutable empty = input.length == 0;
input ~= data; input ~= data;
@ -85,8 +86,8 @@ class IOCPStreamTransport : StreamTransport
} }
} }
class IOCPLoop : Loop class IOCPLoop : Loop
{ {
protected HANDLE completionPort; protected HANDLE completionPort;
protected OVERLAPPED overlap; protected OVERLAPPED overlap;
@ -94,7 +95,7 @@ class IOCPStreamTransport : StreamTransport
/** /**
* Initializes the loop. * Initializes the loop.
*/ */
this() this() @nogc
{ {
super(); super();
@ -118,7 +119,7 @@ class IOCPStreamTransport : StreamTransport
*/ */
override protected bool reify(ConnectionWatcher watcher, override protected bool reify(ConnectionWatcher watcher,
EventMask oldEvents, EventMask oldEvents,
EventMask events) EventMask events) @nogc
{ {
SocketState overlapped; SocketState overlapped;
if (!(oldEvents & Event.accept) && (events & Event.accept)) if (!(oldEvents & Event.accept) && (events & Event.accept))
@ -185,7 +186,7 @@ class IOCPStreamTransport : StreamTransport
/** /**
* Does the actual polling. * Does the actual polling.
*/ */
override protected void poll() override protected void poll() @nogc
{ {
DWORD lpNumberOfBytes; DWORD lpNumberOfBytes;
ULONG_PTR key; ULONG_PTR key;

View File

@ -151,12 +151,13 @@ class KqueueLoop : SelectorLoop
* Returns: Maximal event count can be got at a time * Returns: Maximal event count can be got at a time
* (should be supported by the backend). * (should be supported by the backend).
*/ */
override protected @property inout(uint) maxEvents() inout const pure nothrow @safe @nogc override protected @property inout(uint) maxEvents()
inout const pure nothrow @safe @nogc
{ {
return cast(uint) events.length; return cast(uint) events.length;
} }
this() this() @nogc
{ {
super(); super();
@ -171,14 +172,14 @@ class KqueueLoop : SelectorLoop
/** /**
* Free loop internals. * Free loop internals.
*/ */
~this() ~this() @nogc
{ {
MmapPool.instance.dispose(events); MmapPool.instance.dispose(events);
MmapPool.instance.dispose(changes); MmapPool.instance.dispose(changes);
close(fd); close(fd);
} }
private void set(socket_t socket, short filter, ushort flags) private void set(socket_t socket, short filter, ushort flags) @nogc
{ {
if (changes.length <= changeCount) if (changes.length <= changeCount)
{ {
@ -206,7 +207,7 @@ class KqueueLoop : SelectorLoop
*/ */
override protected bool reify(ConnectionWatcher watcher, override protected bool reify(ConnectionWatcher watcher,
EventMask oldEvents, EventMask oldEvents,
EventMask events) EventMask events) @nogc
{ {
if (events != oldEvents) if (events != oldEvents)
{ {
@ -233,7 +234,7 @@ class KqueueLoop : SelectorLoop
/** /**
* Does the actual polling. * Does the actual polling.
*/ */
protected override void poll() protected override void poll() @nogc
{ {
timespec ts; timespec ts;
blockTime.split!("seconds", "nsecs")(ts.tv_sec, ts.tv_nsec); blockTime.split!("seconds", "nsecs")(ts.tv_sec, ts.tv_nsec);
@ -316,7 +317,7 @@ class KqueueLoop : SelectorLoop
* Returns: The blocking time. * Returns: The blocking time.
*/ */
override protected @property inout(Duration) blockTime() override protected @property inout(Duration) blockTime()
inout @safe pure nothrow inout @nogc @safe pure nothrow
{ {
return min(super.blockTime, 1.dur!"seconds"); return min(super.blockTime, 1.dur!"seconds");
} }
@ -333,7 +334,8 @@ class KqueueLoop : SelectorLoop
* completed or scheduled, $(D_KEYWORD false) otherwise (the * completed or scheduled, $(D_KEYWORD false) otherwise (the
* transport is be destroyed then). * transport is be destroyed then).
*/ */
protected override bool feed(SelectorStreamTransport transport, SocketException exception = null) protected override bool feed(SelectorStreamTransport transport,
SocketException exception = null) @nogc
{ {
if (!super.feed(transport, exception)) if (!super.feed(transport, exception))
{ {

View File

@ -42,7 +42,7 @@ class SelectorStreamTransport : StreamTransport
* loop = Event loop. * loop = Event loop.
* socket = Socket. * socket = Socket.
*/ */
this(SelectorLoop loop, ConnectedSocket socket) this(SelectorLoop loop, ConnectedSocket socket) @nogc
{ {
socket_ = socket; socket_ = socket;
this.loop = loop; this.loop = loop;
@ -52,7 +52,7 @@ class SelectorStreamTransport : StreamTransport
/** /**
* Close the transport and deallocate the data buffers. * Close the transport and deallocate the data buffers.
*/ */
~this() ~this() @nogc
{ {
MmapPool.instance.dispose(input); MmapPool.instance.dispose(input);
} }
@ -71,7 +71,7 @@ class SelectorStreamTransport : StreamTransport
* Params: * Params:
* data = Data to send. * data = Data to send.
*/ */
void write(ubyte[] data) void write(ubyte[] data) @nogc
{ {
if (!data.length) if (!data.length)
{ {
@ -113,13 +113,13 @@ abstract class SelectorLoop : Loop
/// Pending connections. /// Pending connections.
protected ConnectionWatcher[] connections; protected ConnectionWatcher[] connections;
this() this() @nogc
{ {
super(); super();
connections = MmapPool.instance.makeArray!ConnectionWatcher(maxEvents); connections = MmapPool.instance.makeArray!ConnectionWatcher(maxEvents);
} }
~this() ~this() @nogc
{ {
foreach (ref connection; connections) foreach (ref connection; connections)
{ {
@ -147,7 +147,8 @@ abstract class SelectorLoop : Loop
* completed or scheduled, $(D_KEYWORD false) otherwise (the * completed or scheduled, $(D_KEYWORD false) otherwise (the
* transport will be destroyed then). * transport will be destroyed then).
*/ */
protected bool feed(SelectorStreamTransport transport, SocketException exception = null) protected bool feed(SelectorStreamTransport transport,
SocketException exception = null) @nogc
{ {
while (transport.input.length && transport.writeReady) while (transport.input.length && transport.writeReady)
{ {
@ -186,7 +187,7 @@ abstract class SelectorLoop : Loop
* Params: * Params:
* watcher = Watcher. * watcher = Watcher.
*/ */
override void start(ConnectionWatcher watcher) override void start(ConnectionWatcher watcher) @nogc
{ {
if (watcher.active) if (watcher.active)
{ {
@ -208,7 +209,7 @@ abstract class SelectorLoop : Loop
* Params: * Params:
* connection = Connection watcher ready to accept. * connection = Connection watcher ready to accept.
*/ */
package void acceptConnections(ConnectionWatcher connection) package void acceptConnections(ConnectionWatcher connection) @nogc
in in
{ {
assert(connection !is null); assert(connection !is null);

View File

@ -131,15 +131,16 @@ alias EventMask = BitFlags!Event;
abstract class Loop abstract class Loop
{ {
/// Pending watchers. /// Pending watchers.
protected Queue!Watcher pendings; protected Queue!Watcher* pendings;
protected Queue!Watcher swapPendings; protected Queue!Watcher* swapPendings;
/** /**
* Returns: Maximal event count can be got at a time * Returns: Maximal event count can be got at a time
* (should be supported by the backend). * (should be supported by the backend).
*/ */
protected @property inout(uint) maxEvents() inout const pure nothrow @safe @nogc protected @property inout(uint) maxEvents()
inout const pure nothrow @safe @nogc
{ {
return 128U; return 128U;
} }
@ -147,7 +148,7 @@ abstract class Loop
/** /**
* Initializes the loop. * Initializes the loop.
*/ */
this() this() @nogc
{ {
pendings = MmapPool.instance.make!(Queue!Watcher); pendings = MmapPool.instance.make!(Queue!Watcher);
swapPendings = MmapPool.instance.make!(Queue!Watcher); swapPendings = MmapPool.instance.make!(Queue!Watcher);
@ -156,15 +157,15 @@ abstract class Loop
/** /**
* Frees loop internals. * Frees loop internals.
*/ */
~this() ~this() @nogc
{ {
foreach (w; pendings) foreach (w; *pendings)
{ {
MmapPool.instance.dispose(w); MmapPool.instance.dispose(w);
} }
MmapPool.instance.dispose(pendings); MmapPool.instance.dispose(pendings);
foreach (w; swapPendings) foreach (w; *swapPendings)
{ {
MmapPool.instance.dispose(w); MmapPool.instance.dispose(w);
} }
@ -174,7 +175,7 @@ abstract class Loop
/** /**
* Starts the loop. * Starts the loop.
*/ */
void run() void run() @nogc
{ {
done_ = false; done_ = false;
do do
@ -182,7 +183,7 @@ abstract class Loop
poll(); poll();
// Invoke pendings // Invoke pendings
swapPendings.each!((ref p) => p.invoke()); swapPendings.each!((ref p) @nogc => p.invoke());
swap(pendings, swapPendings); swap(pendings, swapPendings);
} }
@ -192,7 +193,7 @@ abstract class Loop
/** /**
* Break out of the loop. * Break out of the loop.
*/ */
void unloop() @safe pure nothrow void unloop() @safe pure nothrow @nogc
{ {
done_ = true; done_ = true;
} }
@ -203,7 +204,7 @@ abstract class Loop
* Params: * Params:
* watcher = Watcher. * watcher = Watcher.
*/ */
void start(ConnectionWatcher watcher) void start(ConnectionWatcher watcher) @nogc
{ {
if (watcher.active) if (watcher.active)
{ {
@ -219,7 +220,7 @@ abstract class Loop
* Params: * Params:
* watcher = Watcher. * watcher = Watcher.
*/ */
void stop(ConnectionWatcher watcher) void stop(ConnectionWatcher watcher) @nogc
{ {
if (!watcher.active) if (!watcher.active)
{ {
@ -242,13 +243,13 @@ abstract class Loop
*/ */
abstract protected bool reify(ConnectionWatcher watcher, abstract protected bool reify(ConnectionWatcher watcher,
EventMask oldEvents, EventMask oldEvents,
EventMask events); EventMask events) @nogc;
/** /**
* Returns: The blocking time. * Returns: The blocking time.
*/ */
protected @property inout(Duration) blockTime() protected @property inout(Duration) blockTime()
inout @safe pure nothrow inout @safe pure nothrow @nogc
{ {
// Don't block if we have to do. // Don't block if we have to do.
return swapPendings.empty ? blockTime_ : Duration.zero; return swapPendings.empty ? blockTime_ : Duration.zero;
@ -261,7 +262,7 @@ abstract class Loop
* blockTime = The blocking time. Cannot be larger than * blockTime = The blocking time. Cannot be larger than
* $(D_PSYMBOL maxBlockTime). * $(D_PSYMBOL maxBlockTime).
*/ */
protected @property void blockTime(in Duration blockTime) @safe pure nothrow protected @property void blockTime(in Duration blockTime) @safe pure nothrow @nogc
in in
{ {
assert(blockTime <= 1.dur!"hours", "Too long to wait."); assert(blockTime <= 1.dur!"hours", "Too long to wait.");
@ -275,7 +276,7 @@ abstract class Loop
/** /**
* Kills the watcher and closes the connection. * Kills the watcher and closes the connection.
*/ */
protected void kill(IOWatcher watcher, SocketException exception) protected void kill(IOWatcher watcher, SocketException exception) @nogc
{ {
watcher.socket.shutdown(); watcher.socket.shutdown();
defaultAllocator.dispose(watcher.socket); defaultAllocator.dispose(watcher.socket);
@ -287,7 +288,7 @@ abstract class Loop
/** /**
* Does the actual polling. * Does the actual polling.
*/ */
abstract protected void poll(); abstract protected void poll() @nogc;
/// Whether the event loop should be stopped. /// Whether the event loop should be stopped.
private bool done_; private bool done_;
@ -321,7 +322,7 @@ class BadLoopException : Exception
* *
* Returns: The default event loop. * Returns: The default event loop.
*/ */
@property Loop defaultLoop() @property Loop defaultLoop() @nogc
{ {
if (defaultLoop_ !is null) if (defaultLoop_ !is null)
{ {
@ -354,7 +355,7 @@ class BadLoopException : Exception
* Params: * Params:
* loop = The event loop. * loop = The event loop.
*/ */
@property void defaultLoop(Loop loop) @property void defaultLoop(Loop loop) @nogc
in in
{ {
assert(loop !is null); assert(loop !is null);

View File

@ -22,7 +22,7 @@ interface Protocol
* Params: * Params:
* data = Read data. * data = Read data.
*/ */
void received(ubyte[] data); void received(ubyte[] data) @nogc;
/** /**
* Called when a connection is made. * Called when a connection is made.
@ -30,7 +30,7 @@ interface Protocol
* Params: * Params:
* transport = Protocol transport. * transport = Protocol transport.
*/ */
void connected(DuplexTransport transport); void connected(DuplexTransport transport) @nogc;
/** /**
* Called when a connection is lost. * Called when a connection is lost.
@ -39,7 +39,7 @@ interface Protocol
* exception = $(D_PSYMBOL Exception) if an error caused * exception = $(D_PSYMBOL Exception) if an error caused
* the disconnect, $(D_KEYWORD null) otherwise. * the disconnect, $(D_KEYWORD null) otherwise.
*/ */
void disconnected(SocketException exception = null); void disconnected(SocketException exception = null) @nogc;
} }
/** /**

View File

@ -37,7 +37,7 @@ interface WriteTransport : Transport
* Params: * Params:
* data = Data to send. * data = Data to send.
*/ */
void write(ubyte[] data); void write(ubyte[] data) @nogc;
} }
/** /**

View File

@ -42,7 +42,7 @@ abstract class Watcher
/** /**
* Invoke some action on event. * Invoke some action on event.
*/ */
void invoke(); void invoke() @nogc;
} }
class ConnectionWatcher : Watcher class ConnectionWatcher : Watcher
@ -51,28 +51,28 @@ class ConnectionWatcher : Watcher
private Socket socket_; private Socket socket_;
/// Protocol factory. /// Protocol factory.
protected Protocol delegate() protocolFactory; protected Protocol delegate() @nogc protocolFactory;
package Queue!IOWatcher incoming; package Queue!IOWatcher* incoming;
/** /**
* Params: * Params:
* socket = Socket. * socket = Socket.
*/ */
this(Socket socket) this(Socket socket) @nogc
{ {
socket_ = socket; socket_ = socket;
incoming = MmapPool.instance.make!(Queue!IOWatcher); incoming = MmapPool.instance.make!(Queue!IOWatcher);
} }
/// Ditto. /// Ditto.
protected this() protected this() pure nothrow @safe @nogc
{ {
} }
~this() ~this() @nogc
{ {
foreach (w; incoming) foreach (w; *incoming)
{ {
MmapPool.instance.dispose(w); MmapPool.instance.dispose(w);
} }
@ -83,9 +83,9 @@ class ConnectionWatcher : Watcher
* Params: * Params:
* P = Protocol should be used. * P = Protocol should be used.
*/ */
void setProtocol(P : Protocol)() void setProtocol(P : Protocol)() @nogc
{ {
this.protocolFactory = () => cast(Protocol) MmapPool.instance.make!P; this.protocolFactory = () @nogc => cast(Protocol) MmapPool.instance.make!P;
} }
/** /**
@ -99,7 +99,7 @@ class ConnectionWatcher : Watcher
/** /**
* Returns: New protocol instance. * Returns: New protocol instance.
*/ */
@property Protocol protocol() @property Protocol protocol() @nogc
in in
{ {
assert(protocolFactory !is null, "Protocol isn't set."); assert(protocolFactory !is null, "Protocol isn't set.");
@ -112,9 +112,9 @@ class ConnectionWatcher : Watcher
/** /**
* Invokes new connection callback. * Invokes new connection callback.
*/ */
override void invoke() override void invoke() @nogc
{ {
foreach (io; incoming) foreach (io; *incoming)
{ {
io.protocol.connected(cast(DuplexTransport) io.transport); io.protocol.connected(cast(DuplexTransport) io.transport);
} }
@ -146,7 +146,7 @@ class IOWatcher : ConnectionWatcher
* transport = Transport. * transport = Transport.
* protocol = New instance of the application protocol. * protocol = New instance of the application protocol.
*/ */
this(StreamTransport transport, Protocol protocol) this(StreamTransport transport, Protocol protocol) @nogc
in in
{ {
assert(transport !is null); assert(transport !is null);
@ -164,7 +164,7 @@ class IOWatcher : ConnectionWatcher
/** /**
* Destroys the watcher. * Destroys the watcher.
*/ */
protected ~this() protected ~this() @nogc
{ {
MmapPool.instance.dispose(output); MmapPool.instance.dispose(output);
MmapPool.instance.dispose(protocol_); MmapPool.instance.dispose(protocol_);
@ -179,7 +179,8 @@ class IOWatcher : ConnectionWatcher
* *
* Returns: $(D_KEYWORD this). * Returns: $(D_KEYWORD this).
*/ */
IOWatcher opCall(StreamTransport transport, Protocol protocol) pure nothrow @nogc IOWatcher opCall(StreamTransport transport, Protocol protocol)
pure nothrow @nogc
in in
{ {
assert(transport !is null); assert(transport !is null);
@ -231,7 +232,7 @@ class IOWatcher : ConnectionWatcher
/** /**
* Invokes the watcher callback. * Invokes the watcher callback.
*/ */
override void invoke() override void invoke() @nogc
{ {
if (output.length) if (output.length)
{ {

View File

@ -18,7 +18,7 @@ import tanya.memory;
* Params: * Params:
* T = Content type. * T = Content type.
*/ */
class Queue(T) struct Queue(T)
{ {
/** /**
* Creates a new $(D_PSYMBOL Queue). * Creates a new $(D_PSYMBOL Queue).
@ -27,7 +27,7 @@ class Queue(T)
* allocator = The allocator should be used for the element * allocator = The allocator should be used for the element
* allocations. * allocations.
*/ */
this(shared Allocator allocator = defaultAllocator) this(shared Allocator allocator)
{ {
this.allocator = allocator; this.allocator = allocator;
} }
@ -86,6 +86,10 @@ class Queue(T)
*/ */
void insertBack(T x) void insertBack(T x)
{ {
if (allocator is null)
{
allocator = defaultAllocator;
}
Entry* temp = make!Entry(allocator); Entry* temp = make!Entry(allocator);
temp.content = x; temp.content = x;
@ -121,7 +125,7 @@ class Queue(T)
/** /**
* Returns: $(D_KEYWORD true) if the queue is empty. * Returns: $(D_KEYWORD true) if the queue is empty.
*/ */
@property bool empty() inout const pure nothrow @safe @nogc @property bool empty() inout const pure nothrow @safe
{ {
return first.next is null; return first.next is null;
} }
@ -146,6 +150,7 @@ class Queue(T)
in in
{ {
assert(!empty); assert(!empty);
assert(allocator !is null);
} }
body body
{ {
@ -176,7 +181,7 @@ class Queue(T)
* Params: * Params:
* dg = $(D_KEYWORD foreach) body. * dg = $(D_KEYWORD foreach) body.
*/ */
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)
{ {
int result; int result;
@ -192,7 +197,7 @@ class Queue(T)
} }
/// Ditto. /// Ditto.
int opApply(scope int delegate(ref T) dg) int opApply(scope int delegate(ref T) @nogc dg)
{ {
int result; int result;
@ -210,7 +215,7 @@ class Queue(T)
/// ///
unittest unittest
{ {
auto q = defaultAllocator.make!(Queue!int); auto q = Queue!int(defaultAllocator);
size_t j; size_t j;
q.insertBack(5); q.insertBack(5);
@ -239,8 +244,6 @@ class Queue(T)
} }
assert(j == 3); assert(j == 3);
assert(q.empty); assert(q.empty);
dispose(defaultAllocator, q);
} }
/** /**
@ -268,7 +271,7 @@ class Queue(T)
/// ///
unittest unittest
{ {
auto q = defaultAllocator.make!(Queue!int); auto q = Queue!int(defaultAllocator);
q.insertBack(5); q.insertBack(5);
assert(!q.empty); assert(!q.empty);
@ -288,6 +291,4 @@ unittest
assert(i != 1 || e == 9); assert(i != 1 || e == 9);
} }
assert(q.empty); assert(q.empty);
defaultAllocator.dispose(q);
} }

View File

@ -15,9 +15,8 @@ import core.stdc.errno;
import core.time; import core.time;
import std.algorithm.comparison; import std.algorithm.comparison;
import std.algorithm.searching; import std.algorithm.searching;
public import std.socket : AddressException, socket_t, Linger, SocketOptionLevel, public import std.socket : socket_t, Linger, SocketOptionLevel, SocketOption,
SocketType, AddressFamily, AddressInfo, SocketType, AddressFamily, AddressInfo;
SocketOption;
import std.traits; import std.traits;
import std.typecons; import std.typecons;
@ -213,7 +212,7 @@ else version (Windows)
* handle = Socket handle. * handle = Socket handle.
* af = Address family. * af = Address family.
*/ */
this(socket_t handle, AddressFamily af) this(socket_t handle, AddressFamily af) @nogc
{ {
super(handle, af); super(handle, af);
} }
@ -233,7 +232,7 @@ else version (Windows)
*/ */
bool beginReceive(ubyte[] buffer, bool beginReceive(ubyte[] buffer,
SocketState overlapped, SocketState overlapped,
Flags flags = Flags(Flag.none)) @trusted Flags flags = Flags(Flag.none)) @nogc @trusted
{ {
auto receiveFlags = cast(DWORD) flags; auto receiveFlags = cast(DWORD) flags;
@ -267,7 +266,7 @@ else version (Windows)
* *
* Throws: $(D_PSYMBOL SocketException) if unable to receive. * Throws: $(D_PSYMBOL SocketException) if unable to receive.
*/ */
int endReceive(SocketState overlapped) @trusted int endReceive(SocketState overlapped) @nogc @trusted
out (count) out (count)
{ {
assert(count >= 0); assert(count >= 0);
@ -306,7 +305,7 @@ else version (Windows)
*/ */
bool beginSend(ubyte[] buffer, bool beginSend(ubyte[] buffer,
SocketState overlapped, SocketState overlapped,
Flags flags = Flags(Flag.none)) @trusted Flags flags = Flags(Flag.none)) @nogc @trusted
{ {
overlapped.handle = cast(HANDLE) handle_; overlapped.handle = cast(HANDLE) handle_;
overlapped.event = OverlappedSocketEvent.write; overlapped.event = OverlappedSocketEvent.write;
@ -339,7 +338,7 @@ else version (Windows)
* *
* Throws: $(D_PSYMBOL SocketException) if unable to receive. * Throws: $(D_PSYMBOL SocketException) if unable to receive.
*/ */
int endSend(SocketState overlapped) @trusted int endSend(SocketState overlapped) @nogc @trusted
out (count) out (count)
{ {
assert(count >= 0); assert(count >= 0);
@ -373,7 +372,7 @@ else version (Windows)
* *
* Throws: $(D_PSYMBOL SocketException) on errors. * Throws: $(D_PSYMBOL SocketException) on errors.
*/ */
this(AddressFamily af) @trusted this(AddressFamily af) @nogc @trusted
{ {
super(af); super(af);
scope (failure) scope (failure)
@ -412,7 +411,7 @@ else version (Windows)
* *
* Throws: $(D_PSYMBOL SocketException) on accept errors. * Throws: $(D_PSYMBOL SocketException) on accept errors.
*/ */
bool beginAccept(SocketState overlapped) @trusted bool beginAccept(SocketState overlapped) @nogc @trusted
{ {
auto socket = cast(socket_t) socket(addressFamily, SOCK_STREAM, 0); auto socket = cast(socket_t) socket(addressFamily, SOCK_STREAM, 0);
if (socket == socket_t.init) if (socket == socket_t.init)
@ -457,7 +456,7 @@ else version (Windows)
* *
* Throws: $(D_PSYMBOL SocketException) if unable to accept. * Throws: $(D_PSYMBOL SocketException) if unable to accept.
*/ */
OverlappedConnectedSocket endAccept(SocketState overlapped) @trusted OverlappedConnectedSocket endAccept(SocketState overlapped) @nogc @trusted
{ {
scope (exit) scope (exit)
{ {
@ -666,7 +665,7 @@ abstract class Socket
/// Address family. /// Address family.
protected AddressFamily family; protected AddressFamily family;
private @property void handle(socket_t handle) private @property void handle(socket_t handle) @nogc
in in
{ {
assert(handle != socket_t.init); assert(handle != socket_t.init);
@ -696,7 +695,7 @@ abstract class Socket
* handle = Socket. * handle = Socket.
* af = Address family. * af = Address family.
*/ */
this(socket_t handle, AddressFamily af) this(socket_t handle, AddressFamily af) @nogc
in in
{ {
assert(handle != socket_t.init); assert(handle != socket_t.init);
@ -731,7 +730,9 @@ abstract class Socket
* *
* Throws: $(D_PSYMBOL SocketException) on error. * Throws: $(D_PSYMBOL SocketException) on error.
*/ */
protected int getOption(SocketOptionLevel level, SocketOption option, void[] result) const @trusted protected int getOption(SocketOptionLevel level,
SocketOption option,
void[] result) const @trusted @nogc
{ {
auto length = cast(socklen_t) result.length; auto length = cast(socklen_t) result.length;
if (getsockopt(handle_, if (getsockopt(handle_,
@ -746,19 +747,25 @@ abstract class Socket
} }
/// Ditto. /// Ditto.
int getOption(SocketOptionLevel level, SocketOption option, out size_t result) const @trusted int getOption(SocketOptionLevel level,
SocketOption option,
out size_t result) const @trusted @nogc
{ {
return getOption(level, option, (&result)[0..1]); return getOption(level, option, (&result)[0..1]);
} }
/// Ditto. /// Ditto.
int getOption(SocketOptionLevel level, SocketOption option, out Linger result) const @trusted int getOption(SocketOptionLevel level,
SocketOption option,
out Linger result) const @trusted @nogc
{ {
return getOption(level, option, (&result.clinger)[0..1]); return getOption(level, option, (&result.clinger)[0..1]);
} }
/// Ditto. /// Ditto.
int getOption(SocketOptionLevel level, SocketOption option, out Duration result) const @trusted int getOption(SocketOptionLevel level,
SocketOption option,
out Duration result) const @trusted @nogc
{ {
// WinSock returns the timeout values as a milliseconds DWORD, // WinSock returns the timeout values as a milliseconds DWORD,
// while Linux and BSD return a timeval struct. // while Linux and BSD return a timeval struct.
@ -791,8 +798,9 @@ abstract class Socket
* *
* Throws: $(D_PSYMBOL SocketException) on error. * Throws: $(D_PSYMBOL SocketException) on error.
*/ */
protected void setOption(SocketOptionLevel level, SocketOption option, void[] value) protected void setOption(SocketOptionLevel level,
const @trusted SocketOption option,
void[] value) const @trusted @nogc
{ {
if (setsockopt(handle_, if (setsockopt(handle_,
cast(int)level, cast(int)level,
@ -805,19 +813,22 @@ abstract class Socket
} }
/// Ditto. /// Ditto.
void setOption(SocketOptionLevel level, SocketOption option, size_t value) const @trusted void setOption(SocketOptionLevel level, SocketOption option, size_t value)
const @trusted @nogc
{ {
setOption(level, option, (&value)[0..1]); setOption(level, option, (&value)[0..1]);
} }
/// Ditto. /// Ditto.
void setOption(SocketOptionLevel level, SocketOption option, Linger value) const @trusted void setOption(SocketOptionLevel level, SocketOption option, Linger value)
const @trusted @nogc
{ {
setOption(level, option, (&value.clinger)[0..1]); setOption(level, option, (&value.clinger)[0..1]);
} }
/// Ditto. /// Ditto.
void setOption(SocketOptionLevel level, SocketOption option, Duration value) const @trusted void setOption(SocketOptionLevel level, SocketOption option, Duration value)
const @trusted @nogc
{ {
version (Posix) version (Posix)
{ {
@ -855,7 +866,7 @@ abstract class Socket
* Params: * Params:
* yes = Socket's blocking flag. * yes = Socket's blocking flag.
*/ */
@property void blocking(bool yes) @property void blocking(bool yes) @nogc
{ {
version (Posix) version (Posix)
{ {
@ -943,7 +954,7 @@ abstract class Socket
* backlog = Request of how many pending incoming connections are * backlog = Request of how many pending incoming connections are
* queued until $(D_PSYMBOL accept)ed. * queued until $(D_PSYMBOL accept)ed.
*/ */
void listen(int backlog) const @trusted void listen(int backlog) const @trusted @nogc
{ {
if (.listen(handle_, backlog) == SOCKET_ERROR) if (.listen(handle_, backlog) == SOCKET_ERROR)
{ {
@ -992,7 +1003,7 @@ class StreamSocket : Socket, ConnectionOrientedSocket
* Params: * Params:
* af = Address family. * af = Address family.
*/ */
this(AddressFamily af) @trusted this(AddressFamily af) @trusted @nogc
{ {
auto handle = cast(socket_t) socket(af, SOCK_STREAM, 0); auto handle = cast(socket_t) socket(af, SOCK_STREAM, 0);
if (handle == socket_t.init) if (handle == socket_t.init)
@ -1010,7 +1021,7 @@ class StreamSocket : Socket, ConnectionOrientedSocket
* *
* Throws: $(D_PSYMBOL SocketException) if unable to bind. * Throws: $(D_PSYMBOL SocketException) if unable to bind.
*/ */
void bind(Address address) @trusted const void bind(Address address) const @trusted @nogc
{ {
if (.bind(handle_, address.name, address.length) == SOCKET_ERROR) if (.bind(handle_, address.name, address.length) == SOCKET_ERROR)
{ {
@ -1029,7 +1040,7 @@ class StreamSocket : Socket, ConnectionOrientedSocket
* *
* Throws: $(D_PSYMBOL SocketException) if unable to accept. * Throws: $(D_PSYMBOL SocketException) if unable to accept.
*/ */
ConnectedSocket accept() @trusted ConnectedSocket accept() @trusted @nogc
{ {
socket_t sock; socket_t sock;
@ -1112,7 +1123,7 @@ class ConnectedSocket : Socket, ConnectionOrientedSocket
* handle = Socket. * handle = Socket.
* af = Address family. * af = Address family.
*/ */
this(socket_t handle, AddressFamily af) this(socket_t handle, AddressFamily af) @nogc
{ {
super(handle, af); super(handle, af);
} }
@ -1148,7 +1159,7 @@ class ConnectedSocket : Socket, ConnectionOrientedSocket
* *
* Throws: $(D_PSYMBOL SocketException) if unable to receive. * Throws: $(D_PSYMBOL SocketException) if unable to receive.
*/ */
ptrdiff_t receive(ubyte[] buf, Flags flags = Flag.none) @trusted ptrdiff_t receive(ubyte[] buf, Flags flags = Flag.none) @trusted @nogc
{ {
ptrdiff_t ret; ptrdiff_t ret;
if (!buf.length) if (!buf.length)
@ -1186,7 +1197,8 @@ class ConnectedSocket : Socket, ConnectionOrientedSocket
* *
* Throws: $(D_PSYMBOL SocketException) if unable to send. * Throws: $(D_PSYMBOL SocketException) if unable to send.
*/ */
ptrdiff_t send(const(ubyte)[] buf, Flags flags = Flag.none) const @trusted ptrdiff_t send(const(ubyte)[] buf, Flags flags = Flag.none)
const @trusted @nogc
{ {
int sendFlags = cast(int) flags; int sendFlags = cast(int) flags;
ptrdiff_t sent; ptrdiff_t sent;
@ -1244,12 +1256,12 @@ class InternetAddress : Address
anyPort = 0, anyPort = 0,
} }
this(in string host, ushort port = anyPort) this(in string host, ushort port = anyPort) @nogc
{ {
if (getaddrinfoPointer is null || freeaddrinfoPointer is null) if (getaddrinfoPointer is null || freeaddrinfoPointer is null)
{ {
throw make!AddressException(defaultAllocator, throw make!SocketException(defaultAllocator,
"Address info lookup is not available on this system"); "Address info lookup is not available on this system");
} }
addrinfo* ai_res; addrinfo* ai_res;
port_ = port; port_ = port;
@ -1285,7 +1297,7 @@ class InternetAddress : Address
auto ret = getaddrinfoPointer(node.ptr, servicePointer, null, &ai_res); auto ret = getaddrinfoPointer(node.ptr, servicePointer, null, &ai_res);
if (ret) if (ret)
{ {
throw defaultAllocator.make!AddressException("Address info lookup failed"); throw defaultAllocator.make!SocketException("Address info lookup failed");
} }
scope (exit) scope (exit)
{ {
@ -1299,7 +1311,7 @@ class InternetAddress : Address
} }
if (ai_res.ai_family != AddressFamily.INET && ai_res.ai_family != AddressFamily.INET6) if (ai_res.ai_family != AddressFamily.INET && ai_res.ai_family != AddressFamily.INET6)
{ {
throw defaultAllocator.make!AddressException("Wrong address family"); throw defaultAllocator.make!SocketException("Wrong address family");
} }
} }