Merge pull request #89 from vibe-d/fix_waitfordataasync_scoped_destruction

Fix waitForDataAsync compilation error for callbacks that have scoped…
merged-on-behalf-of: Leonid Kramer <l-kramer@users.noreply.github.com>
This commit is contained in:
The Dlang Bot 2018-09-03 21:14:24 +02:00 committed by GitHub
commit b5177894d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -619,7 +619,7 @@ mixin(tracer);
if (is(typeof(() @safe { read_ready_callback(true); } ()))) if (is(typeof(() @safe { read_ready_callback(true); } ())))
{ {
mixin(tracer); mixin(tracer);
import vibe.core.core : setTimer; import vibe.core.core : Timer, setTimer;
if (!m_context) if (!m_context)
return WaitForDataAsyncStatus.noMoreData; return WaitForDataAsyncStatus.noMoreData;
@ -632,17 +632,49 @@ mixin(tracer);
return rs ? WaitForDataAsyncStatus.dataAvailable : WaitForDataAsyncStatus.noMoreData; return rs ? WaitForDataAsyncStatus.dataAvailable : WaitForDataAsyncStatus.noMoreData;
} }
auto tm = setTimer(timeout, { static final class WaitContext {
eventDriver.sockets.cancelRead(m_socket); import std.algorithm.mutation : move;
read_ready_callback(false);
}); CALLABLE callback;
eventDriver.sockets.read(m_socket, m_context.readBuffer.peekDst(), IOMode.once, TCPConnection connection;
(sock, st, nb) { Timer timer;
tm.stop();
assert(m_context.readBuffer.length == 0); this(CALLABLE callback, TCPConnection connection, Duration timeout)
m_context.readBuffer.putN(nb); {
read_ready_callback(m_context.readBuffer.length > 0); this.callback = callback;
}); this.connection = connection;
if (timeout < Duration.max)
this.timer = setTimer(timeout, &onTimeout);
}
void onTimeout()
{
eventDriver.sockets.cancelRead(connection.m_socket);
invoke(false);
}
void onData(StreamSocketFD, IOStatus st, size_t nb)
{
if (timer) timer.stop();
assert(connection.m_context.readBuffer.length == 0);
connection.m_context.readBuffer.putN(nb);
invoke(connection.m_context.readBuffer.length > 0);
}
void invoke(bool status)
{
auto cb = move(callback);
connection = TCPConnection.init;
timer = Timer.init;
cb(status);
}
}
// FIXME: make this work without a heap allocation!
auto context = new WaitContext(read_ready_callback, this, timeout);
eventDriver.sockets.read(m_socket, m_context.readBuffer.peekDst(),
IOMode.once, &context.onData);
return WaitForDataAsyncStatus.waiting; return WaitForDataAsyncStatus.waiting;
} }
@ -758,6 +790,20 @@ enum WaitForDataAsyncStatus {
waiting, waiting,
} }
unittest { // test compilation of callback with scoped destruction
static struct CB {
~this() {}
this(this) {}
void opCall(bool) {}
}
void test() {
TCPConnection c;
CB cb;
c.waitForDataAsync(cb);
}
}
mixin validateConnectionStream!TCPConnection; mixin validateConnectionStream!TCPConnection;
@ -1066,4 +1112,4 @@ class ReadTimeoutException: Exception
{ {
super(message, file, line, next); super(message, file, line, next);
} }
} }