Skip to content

Commit

Permalink
SocketAsyncContext.Unix: fix double processing of AsyncOperations (do…
Browse files Browse the repository at this point in the history
…tnet#45683)

* SocketAsyncContext.Unix: fix double processing of AsyncOperations

When a socket event occurs, the pending operations gets triggered
to continue their work by calling the Process method.

The changes in dotnet#37974
cause Process to be called twice on the same AsyncOperation.

When Process is called, the operation can complete, and the
AsyncOperation instance may be reused for a different operation.

* Remove processAsyncEvents
  • Loading branch information
antonfirsov committed Jan 8, 2021
1 parent 988fa3b commit 6e12567
Showing 1 changed file with 5 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ public bool StartAsyncOperation(SocketAsyncContext context, TOperation operation
}
}

public AsyncOperation? ProcessSyncEventOrGetAsyncEvent(SocketAsyncContext context, bool skipAsyncEvents = false, bool processAsyncEvents = true)
public AsyncOperation? ProcessSyncEventOrGetAsyncEvent(SocketAsyncContext context, bool skipAsyncEvents = false)
{
AsyncOperation op;
using (Lock())
Expand All @@ -865,7 +865,6 @@ public bool StartAsyncOperation(SocketAsyncContext context, TOperation operation
Debug.Assert(_isNextOperationSynchronous == (op.Event != null));
if (skipAsyncEvents && !_isNextOperationSynchronous)
{
Debug.Assert(!processAsyncEvents);
// 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;
Expand Down Expand Up @@ -903,11 +902,6 @@ public bool StartAsyncOperation(SocketAsyncContext context, TOperation operation
{
// Async operation. The caller will figure out how to process the IO.
Debug.Assert(!skipAsyncEvents);
if (processAsyncEvents)
{
op.Process();
return null;
}
return op;
}
}
Expand Down Expand Up @@ -2079,12 +2073,14 @@ public void HandleEventsInline(Interop.Sys.SocketEvents events)

if ((events & Interop.Sys.SocketEvents.Read) != 0)
{
_receiveQueue.ProcessSyncEventOrGetAsyncEvent(this, processAsyncEvents: true);
AsyncOperation? receiveOperation = _receiveQueue.ProcessSyncEventOrGetAsyncEvent(this);
receiveOperation?.Process();
}

if ((events & Interop.Sys.SocketEvents.Write) != 0)
{
_sendQueue.ProcessSyncEventOrGetAsyncEvent(this, processAsyncEvents: true);
AsyncOperation? sendOperation = _sendQueue.ProcessSyncEventOrGetAsyncEvent(this);
sendOperation?.Process();
}
}

Expand Down

0 comments on commit 6e12567

Please sign in to comment.