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:
commit
b5177894d2
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue