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 bool TryExecuteSync() { Socket socket = Socket !; (SocketError socketError, Socket? acceptedSocket) = SocketPal.Accept(socket.SafeHandle); AcceptedSocket = acceptedSocket; if (socketError == SocketError.WouldBlock) { return(false); } SocketError = socketError; return(true); }
public override bool TryExecuteSync() { Socket socket = Socket !; IPEndPoint ipEndPoint = (IPEndPoint)EndPoint !; SocketError socketError = SocketPal.Connect(socket.SafeHandle, ipEndPoint); if (socketError == SocketError.InProgress) { return(false); } SocketError = socketError; return(true); }
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) { Socket socket = Socket !; IPEndPoint?ipEndPoint = EndPoint as IPEndPoint; if (ipEndPoint == null) { ThrowHelper.ThrowInvalidOperationException(); } // When there is a pollable executionQueue, use it to poll, and then try the operation. bool hasPollableExecutionQueue = executionQueue?.SupportsPolling == true; bool trySync = !hasPollableExecutionQueue && !asyncOnly; if (trySync || asyncResult.HasResult) { SocketError socketError; if (!_connectCalled) { socketError = SocketPal.Connect(socket.SafeHandle, ipEndPoint); _connectCalled = true; } else { // TODO: read SOL_SOCKET, SO_ERROR to get errorcode... socketError = SocketError.Success; } if (socketError != SocketError.InProgress) { SocketError = socketError; return(AsyncExecutionResult.Finished); } } if (isCancellationRequested) { SocketError = SocketError.OperationAborted; return(AsyncExecutionResult.Cancelled); } // poll if (hasPollableExecutionQueue) { executionQueue !.AddPollOut(socket.SafeHandle, callback !, state, data); return(AsyncExecutionResult.Executing); } else { return(AsyncExecutionResult.WaitForPoll); } }
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 static (SocketError socketError, int bytesTransferred) SendMemory(Socket socket, Memory <byte> memory) { int bytesTransferredTotal = 0; while (true) { Memory <byte> remaining = memory.Slice(bytesTransferredTotal); (SocketError socketError, int bytesTransferred) = SocketPal.Send(socket.SafeHandle, remaining); bytesTransferredTotal += bytesTransferred; if (socketError == SocketError.Success) { if (bytesTransferredTotal != memory.Length && bytesTransferred != 0) { continue; } } return(socketError, bytesTransferredTotal); } }
// This method is called by base.CompletionPortCallback base.OverlappedCallback as part of IO completion internal override unsafe object?PostCompletion(int numBytes) { SocketError errorCode = (SocketError)ErrorCode; Socket socket = (Socket)AsyncObject !; if (errorCode == SocketError.Success) { // Set the socket context. try { errorCode = Interop.Winsock.setsockopt( socket.SafeHandle, SocketOptionLevel.Socket, SocketOptionName.UpdateConnectContext, null, 0); if (errorCode == SocketError.SocketError) { errorCode = SocketPal.GetLastSocketError(); } } catch (ObjectDisposedException) { errorCode = SocketError.OperationAborted; } ErrorCode = (int)errorCode; } if (errorCode == SocketError.Success) { socket.SetToConnected(); return(socket); } return(null); }
public override AsyncExecutionResult TryExecute(bool triggeredByPoll, bool isCancellationRequested, bool asyncOnly, AsyncExecutionQueue?executionQueue, AsyncExecutionCallback?callback, object?state, int data, AsyncOperationResult asyncResult) { Socket socket = Socket !; // When there is a pollable executionQueue, use it to poll, and then try the operation. bool hasPollableExecutionQueue = executionQueue?.SupportsPolling == true; bool trySync = !hasPollableExecutionQueue && !asyncOnly; if (trySync || asyncResult.HasResult) { (SocketError socketError, Socket? acceptedSocket) = SocketPal.Accept(socket.SafeHandle); if (socketError != SocketError.WouldBlock) { SocketError = socketError; AcceptedSocket = acceptedSocket; return(AsyncExecutionResult.Finished); } } if (isCancellationRequested) { SocketError = SocketError.OperationAborted; return(AsyncExecutionResult.Cancelled); } // poll if (hasPollableExecutionQueue) { executionQueue !.AddPollIn(socket.SafeHandle, callback !, state, data);; return(AsyncExecutionResult.Executing); } else { return(AsyncExecutionResult.WaitForPoll); } }
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); }