public override bool TryExecuteSync() { Socket socket = Socket !; (SocketError socketError, int bytesTransferred) = SocketPal.Recv(socket.SafeHandle, MemoryBuffer); BytesTransferred = bytesTransferred; if (socketError == SocketError.WouldBlock) { return(false); } SocketError = socketError; return(true); }
public override AsyncExecutionResult TryExecute(bool triggeredByPoll, bool isCancellationRequested, bool asyncOnly, AsyncExecutionQueue?executionQueue, AsyncExecutionCallback?callback, object?state, int data, AsyncOperationResult asyncResult) { SocketError socketError = SocketError.SocketError; int bytesTransferred = -1; AsyncExecutionResult result = AsyncExecutionResult.Executing; if (asyncResult.HasResult) { if (asyncResult.IsError) { if (asyncResult.Errno == EINTR) { result = AsyncExecutionResult.Executing; } else if (asyncResult.Errno == EAGAIN) { result = AsyncExecutionResult.WaitForPoll; } else { bytesTransferred = 0; socketError = SocketPal.GetSocketErrorForErrno(asyncResult.Errno); result = AsyncExecutionResult.Finished; } } else { bytesTransferred = asyncResult.IntValue; socketError = SocketError.Success; result = AsyncExecutionResult.Finished; } } if (isCancellationRequested && result != AsyncExecutionResult.Finished) { SocketError = SocketError.OperationAborted; return(AsyncExecutionResult.Cancelled); } // When there is a pollable executionQueue, use it to poll, and then try the operation. if (result == AsyncExecutionResult.Executing || (result == AsyncExecutionResult.WaitForPoll && executionQueue?.SupportsPolling == true)) { Memory <byte> memory = MemoryBuffer; bool isPollingReadable = memory.Length == 0; // A zero-byte read is a poll. if (triggeredByPoll && isPollingReadable) { // No need to make a syscall, poll told us we're readable. (socketError, bytesTransferred) = (SocketError.Success, 0); result = AsyncExecutionResult.Finished; } else { Socket socket = Socket !; // Using Linux AIO executionQueue, we can't check when there is no // data available. Instead of return value EAGAIN, a 0-byte read returns '0'. if (executionQueue != null && (!isPollingReadable || executionQueue.SupportsPolling)) // Don't use Linux AIO for 0-byte reads. { executionQueue.AddRead(socket.SafeHandle, memory, callback !, state, data); result = AsyncExecutionResult.Executing; } else if (result == AsyncExecutionResult.Executing) { if (asyncOnly) { result = AsyncExecutionResult.WaitForPoll; } else { (socketError, bytesTransferred) = SocketPal.Recv(socket.SafeHandle, memory); result = socketError == SocketError.WouldBlock ? AsyncExecutionResult.WaitForPoll : AsyncExecutionResult.Finished; } } } } if (result == AsyncExecutionResult.Finished) { Debug.Assert(bytesTransferred != -1); BytesTransferred = bytesTransferred; SocketError = socketError; } return(result); }