Skip to content

Commit

Permalink
Skip processing async operations from epoll thread (dotnet#35940)
Browse files Browse the repository at this point in the history
Fixes dotnet#35330 (comment) by skipping state transitions when an async operation needs to be processed.
  • Loading branch information
kouvel authored May 7, 2020
1 parent 618c1d5 commit faa7456
Showing 1 changed file with 13 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ public bool StartAsyncOperation(SocketAsyncContext context, TOperation operation
}
}

public AsyncOperation? ProcessSyncEventOrGetAsyncEvent(SocketAsyncContext context)
public AsyncOperation? ProcessSyncEventOrGetAsyncEvent(SocketAsyncContext context, bool skipAsyncEvents = false)
{
AsyncOperation op;
using (Lock())
Expand All @@ -860,8 +860,16 @@ public bool StartAsyncOperation(SocketAsyncContext context, TOperation operation

case QueueState.Waiting:
Debug.Assert(_tail != null, "State == Waiting but queue is empty!");
_state = QueueState.Processing;
op = _tail.Next;
Debug.Assert(_isNextOperationSynchronous == (op.Event != null));
if (skipAsyncEvents && !_isNextOperationSynchronous)
{
// Return the operation to indicate that the async operation was not processed, without making
// any state changes because async operations are being skipped
return op;
}

_state = QueueState.Processing;
// Break out and release lock
break;

Expand Down Expand Up @@ -892,6 +900,7 @@ public bool StartAsyncOperation(SocketAsyncContext context, TOperation operation
else
{
// Async operation. The caller will figure out how to process the IO.
Debug.Assert(!skipAsyncEvents);
return op;
}
}
Expand Down Expand Up @@ -1998,14 +2007,14 @@ public unsafe Interop.Sys.SocketEvents HandleSyncEventsSpeculatively(Interop.Sys

if ((events & Interop.Sys.SocketEvents.Read) != 0 &&
_receiveQueue.IsNextOperationSynchronous_Speculative &&
_receiveQueue.ProcessSyncEventOrGetAsyncEvent(this) == null)
_receiveQueue.ProcessSyncEventOrGetAsyncEvent(this, skipAsyncEvents: true) == null)
{
events ^= Interop.Sys.SocketEvents.Read;
}

if ((events & Interop.Sys.SocketEvents.Write) != 0 &&
_sendQueue.IsNextOperationSynchronous_Speculative &&
_sendQueue.ProcessSyncEventOrGetAsyncEvent(this) == null)
_sendQueue.ProcessSyncEventOrGetAsyncEvent(this, skipAsyncEvents: true) == null)
{
events ^= Interop.Sys.SocketEvents.Write;
}
Expand Down

0 comments on commit faa7456

Please sign in to comment.