Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Plumb CancellationToken through Socket.Receive/SendAsync #36516

Merged
merged 1 commit into from
Apr 7, 2019

Commits on Apr 1, 2019

  1. Plumb CancellationToken through Socket.Receive/SendAsync

    In .NET Core 2.1 we added overloads of Send/ReceiveAsync, and we proactively added CancellationToken arguments to them, but those tokens were only checked at the beginning of the call; if a cancellation request came in after that check, the operation would not be interrupted.
    
    This PR plumbs the token through so that a cancellation request at any point in the operation will cancel that operation.  On Windows we register to use CancelIoEx to request cancellation of the specific overlapped operation on the specific socket.  On Unix we use the existing cancellation infrastructure already in place to support the existing custom queueing scheme.
    
    Some caveats:
    - On Windows, canceling a TCP receive will end up canceling all TCP receives pending on that socket, even when we request cancellation of a specific overlapped operation; this is just how cancellation works at the OS level, and there's little we can do about it.  It also shouldn't matter much, as multiple pending receives on the same socket are rare.
    - If multiple concurrent receives or multiple concurrent sends are issued on the same socket, only the first will actually be cancelable.  This is because this implementation only plumbs the token through the SocketAsyncEventArgs-based code paths, not the APM based code paths, and currently when using the Task-based APIs, we use the SocketAsyncEventArgs under the covers for only one receive and one send at a time; other receives made while that SAEA receive is in progress or other sends made while that SAEA send is in progress will fall back to using the APM code paths.  This could be addressed in the future in various ways, including a) just using the SAEA code paths for all operations and deleting the APM fallback, or b) plumbing cancellation through APM as well.  However, for now, this approach addresses the primary use case and should be sufficient.
    - This only affects code paths to which the CancellationToken passed to Send/ReceiveAsync could reach.  If in the future we add additional overloads taking CancellationToken, we will likely need to plumb it to more places.
    stephentoub committed Apr 1, 2019
    Configuration menu
    Copy the full SHA
    d78c103 View commit details
    Browse the repository at this point in the history