Skip to content
Open
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -787,11 +787,13 @@ private unsafe int ProcessRead(SerialStreamIORequest r)
{
Interop.ErrorInfo lastError = Interop.Sys.GetLastErrorInfo();

// ignore EWOULDBLOCK since we handle timeout elsewhere
if (lastError.Error != Interop.Error.EWOULDBLOCK)
if (lastError.Error == Interop.Error.EWOULDBLOCK)
{
readRequest.Complete(Interop.GetIOException(lastError));
// no data available right now, signal caller to stop draining
return -1;
}

readRequest.Complete(Interop.GetIOException(lastError));
}
else if (numBytes > 0)
{
Expand Down Expand Up @@ -820,9 +822,13 @@ private unsafe int ProcessWrite(SerialStreamIORequest r)
{
Interop.ErrorInfo lastError = Interop.Sys.GetLastErrorInfo();

// ignore EWOULDBLOCK since we handle timeout elsewhere
// numBytes == 0 means that there might be an error
if (lastError.Error != Interop.Error.SUCCESS && lastError.Error != Interop.Error.EWOULDBLOCK)
if (lastError.Error == Interop.Error.EWOULDBLOCK)
{
// write buffer full right now, signal caller to stop draining
return -1;
}

if (lastError.Error != Interop.Error.SUCCESS)
{
r.Complete(Interop.GetIOException(lastError));
}
Expand Down Expand Up @@ -850,7 +856,12 @@ private static int DoIORequest(Queue<SerialStreamIORequest> q, object queueLock,
while (TryPeekNextRequest(out SerialStreamIORequest r))
{
int ret = op(r);
Debug.Assert(ret >= 0);

if (ret < 0)
{
// EWOULDBLOCK — no data available right now, propagate to caller
return -1;
}

if (r.IsCompleted)
{
Expand Down Expand Up @@ -947,9 +958,9 @@ private void IOLoop()
else
{
Interop.PollEvents events = PollEvents(1,
pollReadEvents: hasPendingReads,
pollWriteEvents: hasPendingWrites,
out Interop.ErrorInfo? error);
pollReadEvents: hasPendingReads,
pollWriteEvents: hasPendingWrites,
out Interop.ErrorInfo? error);

if (error.HasValue)
{
Expand All @@ -967,13 +978,23 @@ private void IOLoop()

if (events.HasFlag(Interop.PollEvents.POLLIN))
{
int bytesRead = DoIORequest(_readQueue, _readQueueLock, _processReadDelegate);
_totalBytesRead += bytesRead;
// drain all requests that have data ready right now
// without paying another 1ms poll cost per request
while (!IsReadQueueEmpty())
{
int bytesRead = DoIORequest(_readQueue, _readQueueLock, _processReadDelegate);
if (bytesRead <= 0) break; // 0 = queue empty, -1 = EWOULDBLOCK
_totalBytesRead += bytesRead;
}
}

if (events.HasFlag(Interop.PollEvents.POLLOUT))
{
DoIORequest(_writeQueue, _writeQueueLock, _processWriteDelegate);
// flush as many pending write requests as possible
while (!IsWriteQueueEmpty())
{
if (DoIORequest(_writeQueue, _writeQueueLock, _processWriteDelegate) <= 0) break;
}
}
}

Expand Down
Loading