예제 #1
0
 public override void AddWrite(SafeHandle handle, Memory <byte> memory, IAsyncExecutionResultHandler callback, int data)
 {
     if (_scheduledOperations == null)
     {
         _scheduledOperations = new List <Operation>();
     }
     _scheduledOperations.Add(new Operation {
         Handle = handle, Memory = memory, IsReadNotWrite = false, ResultHandler = callback
     });
 }
예제 #2
0
            public override void AddPollOut(SafeHandle handle, IAsyncExecutionResultHandler callback, int data)
            {
                ulong     key       = CalculateKey(handle, data);
                Operation operation = RentOperation();

                operation.Handle        = handle;
                operation.OperationType = OperationType.PollOut;
                operation.ResultHandler = callback;
                operation.Data          = data;
                AddNewOperation(key, operation);
            }
예제 #3
0
 public override void AddRead(SafeHandle handle, Memory <byte> memory, IAsyncExecutionResultHandler callback, int data)
 {
     if (memory.Length == 0)
     {
         ThrowHelper.ThrowArgumentException(nameof(memory));
     }
     if (_scheduledOperations == null)
     {
         _scheduledOperations = new List <Operation>();
     }
     _scheduledOperations.Add(new Operation {
         Handle = handle, Memory = memory, IsReadNotWrite = true, ResultHandler = callback
     });
 }
예제 #4
0
            public override void AddWrite(SafeHandle handle, Memory <byte> memory, IAsyncExecutionResultHandler callback, int data)
            {
                ulong     key       = CalculateKey(handle, data);
                Operation operation = RentOperation();

                operation.Handle        = handle;
                operation.Memory        = memory;
                operation.OperationType = OperationType.Write;
                operation.ResultHandler = callback;
                operation.Data          = data;

                // Since we can not do linked R/W in 5.5, we'll need to submit a poll first:
                operation.Status = OperationStatus.PollForReadWrite;

                AddNewOperation(key, operation);
            }
예제 #5
0
            public override void AddRead(SafeHandle handle, Memory <byte> memory, IAsyncExecutionResultHandler callback, int data)
            {
                // TODO: maybe consider writing directly to the sq
                //       This requires handling sq full
                //       which may require handling completions
                //       which means we should no longer call this under a lock from the AsyncContext...
                ulong     key       = CalculateKey(handle, data);
                Operation operation = RentOperation();

                operation.Handle        = handle;
                operation.Memory        = memory;
                operation.OperationType = OperationType.Read;
                operation.ResultHandler = callback;
                operation.Data          = data;

                // Since we can not do linked R/W in 5.5, we'll need to submit a poll first:
                operation.Status = OperationStatus.PollForReadWrite;

                AddNewOperation(key, operation);
            }
예제 #6
0
            public void ExecuteCompletions()
            {
                while (_ring !.TryRead(out Completion completion))
                {
                    ulong key = completion.userData;
                    if ((key & PollMaskBit) != 0)
                    {
                        if (key != IgnoredData)
                        {
                            // must be a completion for a poll for R/W
                            _operations.TryGetValue(key & ~PollMaskBit, out Operation? op);
                            Debug.Assert(op != null);
                            Debug.Assert(op.Status == OperationStatus.PollForReadWrite);
                            Debug.Assert(completion.result > 0);
                            op.Status = OperationStatus.Execution;

                            // Re-adding the operation to submit R/W:
                            _newOperations.Add(op);
                        }
                    }
                    else
                    {
                        _operations.Remove(key, out Operation? op);
                        Debug.Assert(op != null);
                        // Clean up
                        op.MemoryHandle.Dispose();

                        // Capture state
                        int data = op.Data;
                        IAsyncExecutionResultHandler handler = op.ResultHandler !;

                        // Return the operation
                        ReturnOperation(op);

                        // Complete
                        handler.HandleAsyncResult(new AsyncOperationResult(completion.result));
                    }
                }
            }
예제 #7
0
 public override void AddPollOut(SafeHandle handle, IAsyncExecutionResultHandler asyncExecutionCallback, int data)
 {
     throw new NotSupportedException();
 }
예제 #8
0
        public override AsyncExecutionResult TryExecuteIOUringAsync(AsyncExecutionQueue executionQueue, IAsyncExecutionResultHandler callback, int key)
        {
            Socket socket = Socket !;

            executionQueue !.AddPollIn(socket.SafeHandle, callback !, key);
            return(AsyncExecutionResult.Executing);
        }
예제 #9
0
        public override AsyncExecutionResult TryExecuteEpollAsync(bool triggeredByPoll, AsyncExecutionQueue?executionQueue, IAsyncExecutionResultHandler callback)
        {
            bool finished = TryExecuteSync();

            return(finished ? AsyncExecutionResult.Finished : AsyncExecutionResult.WaitForPoll);
        }
예제 #10
0
 public override AsyncExecutionResult TryExecuteEpollAsync(bool triggeredByPoll, AsyncExecutionQueue?executionQueue, IAsyncExecutionResultHandler callback)
 {
     if (!_connectCalled)
     {
         _connectCalled = true;
         bool finished = TryExecuteSync();
         return(finished ? AsyncExecutionResult.Finished : AsyncExecutionResult.WaitForPoll);
     }
     else
     {
         if (triggeredByPoll)
         {
             // TODO: read SOL_SOCKET, SO_ERROR to get errorcode...
             SocketError = SocketError.Success;
             return(AsyncExecutionResult.Finished);
         }
         return(AsyncExecutionResult.WaitForPoll);
     }
 }
예제 #11
0
 // Add a poll out.
 public abstract void AddPollOut(SafeHandle handle, IAsyncExecutionResultHandler asyncExecutionCallback, int data);
예제 #12
0
 public override AsyncExecutionResult TryExecuteEpollAsync(bool triggeredByPoll, AsyncExecutionQueue?executionQueue, IAsyncExecutionResultHandler callback)
 => throw new System.InvalidOperationException();
예제 #13
0
        private AsyncExecutionResult TryExecuteSingleBufferAsync(Memory <byte> memory, AsyncExecutionQueue executionQueue, IAsyncExecutionResultHandler callback, int data)
        {
            Socket socket = Socket !;

            executionQueue.AddWrite(socket.SafeHandle, memory, callback, data);
            return(AsyncExecutionResult.Executing);
        }
예제 #14
0
        private AsyncExecutionResult TryExecuteMultipleBuffersAsync(IList <ArraySegment <byte> > buffers, AsyncExecutionQueue executionQueue, IAsyncExecutionResultHandler callback, int data)
        {
            Socket        socket = Socket !;
            Memory <byte> memory = buffers[_bufferIndex].Slice(_bufferOffset);

            executionQueue.AddWrite(socket.SafeHandle, memory, callback, data);
            return(AsyncExecutionResult.Executing);
        }
예제 #15
0
        public AsyncExecutionResult TryExecuteAsync(AsyncExecutionQueue executionQueue, IAsyncExecutionResultHandler callback, int data)
        {
            IList <ArraySegment <byte> >?bufferList = BufferList;

            if (bufferList == null)
            {
                return(TryExecuteSingleBufferAsync(MemoryBuffer.Slice(BytesTransferred), executionQueue, callback, data));
            }
            else
            {
                return(TryExecuteMultipleBuffersAsync(bufferList, executionQueue, callback, data));
            }
        }
예제 #16
0
 public override AsyncExecutionResult TryExecuteIOUringAsync(AsyncExecutionQueue executionQueue, IAsyncExecutionResultHandler callback, int key)
 {
     return(TryExecuteAsync(executionQueue, callback, data: key));
 }
예제 #17
0
 public override AsyncExecutionResult TryExecuteEpollAsync(bool triggeredByPoll, AsyncExecutionQueue?executionQueue, IAsyncExecutionResultHandler callback)
 {
     if (executionQueue != null)
     {
         return(TryExecuteAsync(executionQueue, callback, data: 0));
     }
     else
     {
         bool finished = TryExecuteSync();
         return(finished ? AsyncExecutionResult.Finished : AsyncExecutionResult.WaitForPoll);
     }
 }
예제 #18
0
        public override AsyncExecutionResult TryExecuteIOUringAsync(AsyncExecutionQueue executionQueue, IAsyncExecutionResultHandler callback, int key)
        {
            Socket socket = Socket !;

            executionQueue.AddRead(socket.SafeHandle, MemoryBuffer, callback !, data: key);
            return(AsyncExecutionResult.Executing);
        }
예제 #19
0
 // Add a write.
 public abstract void AddWrite(SafeHandle handle, Memory <byte> memory, IAsyncExecutionResultHandler callback, int data);
예제 #20
0
 public override AsyncExecutionResult TryExecuteIOUringAsync(AsyncExecutionQueue executionQueue, IAsyncExecutionResultHandler callback, int key)
 => throw new System.InvalidOperationException();
예제 #21
0
        public override AsyncExecutionResult TryExecuteEpollAsync(bool triggeredByPoll, AsyncExecutionQueue?executionQueue, IAsyncExecutionResultHandler callback)
        {
            Memory <byte> memory            = MemoryBuffer;
            bool          isPollingReadable = memory.Length == 0; // A zero-byte read is a poll.

            if (executionQueue != null && !isPollingReadable)
            {
                Socket socket = Socket !;
                executionQueue.AddRead(socket.SafeHandle, MemoryBuffer, callback !, data: 0);
                return(AsyncExecutionResult.Executing);
            }
            else
            {
                if (triggeredByPoll && isPollingReadable)
                {
                    // No need to make a syscall, poll told us we're readable.
                    SocketError      = SocketError.Success;
                    BytesTransferred = 0;
                    return(AsyncExecutionResult.Finished);
                }
                bool finished = TryExecuteSync();
                return(finished ? AsyncExecutionResult.Finished : AsyncExecutionResult.WaitForPoll);
            }
        }