Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCPConnection.waitForDataAsync #62

Merged
merged 5 commits into from
Feb 26, 2018
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions source/vibe/core/net.d
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,41 @@ mixin(tracer);
return m_context.readBuffer.length > 0;
}

enum WaitForDataAsyncStatus {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To reduce the amount of text to type when using this from the outside, I'd move this outside below the TCPConnection class.

noMoreData,
dataAvailable,
waiting
}

WaitForDataAsyncStatus waitForDataAsync(void delegate(bool) @safe read_callback, Duration timeout = Duration.max)
{
mixin(tracer);
import vibe.core.core : runTask, setTimer, createTimer;

if (!m_context) {
runTask(read_callback, false);
return WaitForDataAsyncStatus.noMoreData;
}
if (m_context.readBuffer.length > 0) {
runTask(read_callback, true);
return WaitForDataAsyncStatus.dataAvailable;
}

if (timeout <= 0.seconds) {
auto rs = waitForData(0.seconds);
auto mode = rs ? WaitForDataAsyncStatus.dataAvailable : WaitForDataAsyncStatus.noMoreData;
return mode;
}

auto tm = setTimer(timeout, { eventDriver.sockets.cancelRead(m_socket);
runTask(read_callback, false); });
eventDriver.sockets.read(m_socket, m_context.readBuffer.peekDst(), IOMode.once,
(sock, st, nb) { tm.stop(); if(st != IOStatus.ok) runTask(read_callback, false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two lines from above

assert(m_context.readBuffer.length == 0);
m_context.readBuffer.putN(nbytes);``

should be executed right after the tm.stop(), so that the read data is actually committed to the read buffer. The if condition would then ideally be m_context.readBuffer.length > 0 instead of st == IOStatus.ok, because partial data could have been read before the error was raised (not a realistic case, since IOMode.once is used, but handling it this way should be slightly more robust).

else runTask(read_callback, true);
});
return WaitForDataAsyncStatus.waiting;
}

const(ubyte)[] peek() { return m_context ? m_context.readBuffer.peek() : null; }

void skip(ulong count)
Expand Down