Merge pull request #30 from vibe-d/improve_cancel_conn

Improve cancelStreamConnection and implement on Win32
merged-on-behalf-of: Sönke Ludwig <s-ludwig@users.noreply.github.com>
This commit is contained in:
The Dlang Bot 2017-11-12 15:02:36 +01:00 committed by GitHub
commit 88bfabf557
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 1 deletions

View file

@ -128,6 +128,19 @@ interface EventDriverSockets {
StreamSocketFD connectStream(scope Address peer_address, scope Address bind_address, ConnectCallback on_connect); StreamSocketFD connectStream(scope Address peer_address, scope Address bind_address, ConnectCallback on_connect);
/** Aborts asynchronous connect by closing the socket. /** Aborts asynchronous connect by closing the socket.
This function may only invoked if the connection state is
`ConnectionState.connecting`. It will cancel the connection attempt and
guarantees that the connection callback will not be invoked in the
future.
Note that upon completion, the socket handle will be invalid, regardless
of the number of calls to `addRef`, and must not be used for further
operations.
Params:
sock = Handle of the socket that is currently establishing a
connection
*/ */
void cancelConnectStream(StreamSocketFD sock); void cancelConnectStream(StreamSocketFD sock);

View file

@ -84,7 +84,15 @@ final class WinAPIEventDriverSockets : EventDriverSockets {
final override void cancelConnectStream(StreamSocketFD sock) final override void cancelConnectStream(StreamSocketFD sock)
{ {
assert(false, "Not implemented"); assert(sock != StreamSocketFD.invalid, "Invalid socket descriptor");
with (m_sockets[sock].streamSocket) {
assert(state == ConnectionState.connecting,
"Must be in 'connecting' state when calling cancelConnection.");
clearSocketSlot(sock);
() @trusted { closesocket(sock); } ();
}
} }
override StreamSocketFD adoptStream(int socket) override StreamSocketFD adoptStream(int socket)

40
tests/0-tcp-cancelconn.d Normal file
View file

@ -0,0 +1,40 @@
/++ dub.sdl:
name "test"
dependency "eventcore" path=".."
+/
module test;
import eventcore.core;
import eventcore.socket;
import std.socket : parseAddress;
import core.time : Duration, msecs;
ubyte[256] s_rbuf;
bool s_done;
void main()
{
// (hopefully) non-existant host, so that the connection times out
auto baddr = parseAddress("192.0.2.1", 1);
auto sock = eventDriver.sockets.connectStream(baddr, null, (sock, status) {
assert(false, "Connection callback should not have been called.");
});
assert(sock != StreamSocketFD.invalid, "Expected connection to be in progress.");
assert(eventDriver.sockets.getConnectionState(sock) == ConnectionState.connecting);
auto tm = eventDriver.timers.create();
eventDriver.timers.set(tm, 100.msecs, 0.msecs);
eventDriver.timers.wait(tm, (tm) {
assert(eventDriver.sockets.getConnectionState(sock) == ConnectionState.connecting);
eventDriver.sockets.cancelConnectStream(sock);
s_done = true;
});
ExitReason er;
do er = eventDriver.core.processEvents(Duration.max);
while (er == ExitReason.idle);
assert(er == ExitReason.outOfWaiters);
assert(s_done);
s_done = false;
}