예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }