public override AsyncExecutionResult HandleAsyncResult(AsyncOperationResult asyncResult) { if (asyncResult.Errno == 0) { BytesTransferred = asyncResult.IntValue; SocketError = SocketError.Success; return(AsyncExecutionResult.Finished); } else if (asyncResult.Errno == EINTR) { return(AsyncExecutionResult.Executing); } else if (asyncResult.Errno == ECANCELED) { return(AsyncExecutionResult.Cancelled); } else if (asyncResult.Errno == EAGAIN) { return(AsyncExecutionResult.WaitForPoll); } else { SocketError = SocketPal.GetSocketErrorForErrno(asyncResult.Errno); return(AsyncExecutionResult.Finished); } }
public override AsyncExecutionResult HandleAsyncResult(AsyncOperationResult asyncResult) { if (asyncResult.Errno == 0) { BytesTransferred += asyncResult.IntValue; IList <ArraySegment <byte> >?bufferList = BufferList; if (bufferList == null) { if (BytesTransferred == MemoryBuffer.Length) { SocketError = SocketError.Success; return(AsyncExecutionResult.Finished); } } else { _bufferOffset += asyncResult.IntValue; if (_bufferOffset == bufferList[_bufferIndex].Count) { _bufferOffset = 0; _bufferIndex++; if (_bufferIndex == bufferList.Count) { SocketError = SocketError.Success; return(AsyncExecutionResult.Finished); } } } return(AsyncExecutionResult.Executing); } else if (asyncResult.Errno == EINTR) { return(AsyncExecutionResult.Executing); } else if (asyncResult.Errno == ECANCELED) { return(AsyncExecutionResult.Cancelled); } else if (asyncResult.Errno == EAGAIN) { return(AsyncExecutionResult.WaitForPoll); } else { SocketError = SocketPal.GetSocketErrorForErrno(asyncResult.Errno); return(AsyncExecutionResult.Finished); } }
private AsyncExecutionResult SendSingleBuffer(Memory <byte> memory, bool isCancellationRequested, bool asyncOnly, AsyncExecutionQueue?executionQueue, AsyncExecutionCallback?callback, object?state, int data, AsyncOperationResult asyncResult) { SocketError socketError = SocketError.SocketError; 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 { socketError = SocketPal.GetSocketErrorForErrno(asyncResult.Errno); result = AsyncExecutionResult.Finished; } } else { BytesTransferred += asyncResult.IntValue; if (BytesTransferred == memory.Length) { 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)) { Socket socket = Socket !; if (socket == null) { ThrowHelper.ThrowInvalidOperationException(); } if (executionQueue != null) { Memory <byte> remaining = memory.Slice(BytesTransferred); executionQueue.AddWrite(socket.SafeHandle, remaining, callback !, state, data); result = AsyncExecutionResult.Executing; } else if (result == AsyncExecutionResult.Executing) { if (asyncOnly) { result = AsyncExecutionResult.WaitForPoll; } else { while (true) { Memory <byte> remaining = memory.Slice(BytesTransferred); int bytesTransferred; (socketError, bytesTransferred) = SocketPal.Send(socket.SafeHandle, remaining); if (socketError == SocketError.Success) { BytesTransferred += bytesTransferred; if (BytesTransferred == memory.Length || bytesTransferred == 0) { break; } } else { break; } } result = socketError == SocketError.WouldBlock ? AsyncExecutionResult.WaitForPoll : AsyncExecutionResult.Finished; } } } if (result == AsyncExecutionResult.Finished) { SocketError = socketError; } return(result); }
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); }