示例#1
0
        protected bool IncompleteWrite(bool scheduleAsync, SocketChannelAsyncOperation <TChannel, TUnsafe> operation)
        {
            // Did not write completely.
            if (scheduleAsync)
            {
                SetState(StateFlags.WriteScheduled);
                bool pending;

                using (ExecutionContext.IsFlowSuppressed() ? default(AsyncFlowControl?) : ExecutionContext.SuppressFlow())
                {
                    pending = Socket.SendAsync(operation);
                }

                if (!pending)
                {
                    Unsafe.FinishWrite(operation);
                }

                return(pending);
            }
            else
            {
                // Schedule flush again later so other tasks can be picked up input the meantime
                EventLoop.Execute(FlushAction, this);

                return(true);
            }
        }
        //protected override IChannelUnsafe NewUnsafe() => new SocketByteChannelUnsafe(this); ## 苦竹 屏蔽 ##

        protected override void ScheduleSocketRead()
        {
            var  operation = ReadOperation;
            bool pending;

#if NETCOREAPP || NETSTANDARD
            pending = Socket.ReceiveAsync(operation);
#else
            if (ExecutionContext.IsFlowSuppressed())
            {
                pending = Socket.ReceiveAsync(operation);
            }
            else
            {
                using (ExecutionContext.SuppressFlow())
                {
                    pending = Socket.ReceiveAsync(operation);
                }
            }
#endif
            if (!pending)
            {
                // todo: potential allocation / non-static field?
                EventLoop.Execute(ReadCompletedSyncCallback, Unsafe, operation);
            }
        }
示例#3
0
 /// <summary>
 /// Schedules the send buffer to begin draining
 /// </summary>
 protected void Schedule()
 {
     //only schedule if we're idle
     if (Interlocked.Exchange(ref IsIdle, SendBufferProcessingStatus.Busy) == SendBufferProcessingStatus.Idle)
     {
         EventLoop.Execute(Run);
     }
 }
        protected override void ScheduleSocketRead()
        {
            var operation = ReadOperation;
            var pending   = Socket.ReceiveAsync(operation);

            if (!pending)
            {
                // todo: potential allocation / non-static field?
                EventLoop.Execute(ReadCompletedSyncCallback, Unsafe, operation);
            }
        }
示例#5
0
        protected override void DoBeginRead()
        {
            if (_readInProgress)
            {
                return;
            }

            var pipeline      = Pipeline;
            var inboundBuffer = _inboundBuffer;

            if (!inboundBuffer.Any())
            {
                _readInProgress = true;
                return;
            }

            var stackDepth = _stackDepth.Value;

            if (stackDepth < MAX_READER_STACK_DEPTH)
            {
                _stackDepth.Value = stackDepth + 1;
                try
                {
                    while (true)
                    {
                        if (inboundBuffer.Count == 0)
                        {
                            break;
                        }
                        var received = inboundBuffer.Dequeue();
                        pipeline.FireChannelRead(received);
                    }
                    pipeline.FireChannelReadComplete();
                }
                finally
                {
                    _stackDepth.Value = stackDepth;
                }
            }
            else
            {
                try
                {
                    EventLoop.Execute(_readTask);
                }
                catch (Exception)
                {
                    ReleaseInboundBuffers();
                    throw;
                }
            }
        }
示例#6
0
        public LocalChannel Serve(LocalChannel peer)
        {
            var child = new LocalChannel(this, peer);

            if (EventLoop.InEventLoop)
            {
                Serve0(child);
            }
            else
            {
                EventLoop.Execute(ServeAction, this, child);
            }
            return(child);
        }
示例#7
0
        public LocalChannel Serve(LocalChannel peer)
        {
            LocalChannel child = NewLocalChannel(peer);

            if (EventLoop.InEventLoop)
            {
                Serve0(child);
            }
            else
            {
                EventLoop.Execute(() => Serve0(child));
            }
            return(child);
        }
示例#8
0
        protected void Run()
        {
            if (WasDisposed || !IsOpen())
            {
                return;
            }

            //Set the deadline timer for this run
            var deadlineTimer = Deadline.Now + Timeout;

            //we are about to process all enqueued messages
            HasUnsentMessages = false;

            //we should process x messages in this run
            var left = Throughput;

            NetworkData message;

            while (SendQueue.TryTake(out message))
            {
                SendInternal(message.Buffer, 0, message.Length, message.RemoteHost);
                left--;
                if (WasDisposed)
                {
                    return;
                }

                //if the deadline has expired, stop and break
                if (deadlineTimer.IsOverdue || left == 0)
                {
                    break; //we're done for this run
                }
            }

            //there are still unsent messages that need to be processed
            if (SendQueue.Count > 0)
            {
                HasUnsentMessages = true;
            }

            if (HasUnsentMessages)
            {
                EventLoop.Execute(Run);
            }
            else
            {
                Interlocked.Exchange(ref IsIdle, SendBufferProcessingStatus.Idle);
            }
        }
示例#9
0
        protected override void ScheduleSocketRead()
        {
            var  operation = ReadOperation;
            bool pending;

            using (ExecutionContext.IsFlowSuppressed() ? default(AsyncFlowControl?) : ExecutionContext.SuppressFlow())
            {
                pending = Socket.ReceiveAsync(operation);
            }
            if (!pending)
            {
                // todo: potential allocation / non-static field?
                EventLoop.Execute(ReadCompletedSyncCallback, Unsafe, operation);
            }
        }
示例#10
0
        private void FireChannelWritabilityChanged(bool invokeLater)
        {
            var pipeline = _pipeline;

            if (invokeLater)
            {
                var task = _fireChannelWritabilityChangedTask;
                if (task is null)
                {
                    _fireChannelWritabilityChangedTask = task = InvokeFireChannelWritabilityChangedAction;
                }
                EventLoop.Execute(task, pipeline);
            }
            else
            {
                _ = pipeline.FireChannelWritabilityChanged();
            }
        }
示例#11
0
        protected override void DoBeginRead()
        {
            if (SharedConstants.False < (uint)Volatile.Read(ref v_readInProgress))
            {
                return;
            }

            if (_inboundBuffer.IsEmpty)
            {
                _ = Interlocked.Exchange(ref v_readInProgress, SharedConstants.True);
                return;
            }

            InternalThreadLocalMap threadLocals = InternalThreadLocalMap.Get();
            int stackDepth = threadLocals.LocalChannelReaderStackDepth;

            if (stackDepth < MAX_READER_STACK_DEPTH)
            {
                threadLocals.LocalChannelReaderStackDepth = stackDepth + 1;

                try
                {
                    ReadInbound();
                }
                finally
                {
                    threadLocals.LocalChannelReaderStackDepth = stackDepth;
                }
            }
            else
            {
                try
                {
                    EventLoop.Execute(InternalReadAction, this);
                }
                catch (Exception ex)
                {
                    Logger.Warn("Closing Local channels {}-{} because exception occurred!", this, Volatile.Read(ref v_peer), ex);
                    _ = CloseAsync();
                    _ = Volatile.Read(ref v_peer).CloseAsync();
                    throw;
                }
            }
        }
        protected void IncompleteWrite(bool scheduleAsync, IByteBuf buffer)
        {
            // Did not write completely.
            if (scheduleAsync)
            {
                var operation = PrepareWriteOperation(buffer);

                SetState(StateFlags.WriteScheduled);
                var pending = Socket.SendAsync(operation);
                if (!pending)
                {
                    ((ISocketChannelUnsafe)Unsafe).FinishWrite(operation);
                }
            }
            else
            {
                // Schedule flush again later so other tasks can be picked up input the meantime
                EventLoop.Execute(FlushAction, this);
            }
        }
        protected bool IncompleteWrite(bool scheduleAsync, SocketChannelAsyncOperation <TChannel, TUnsafe> operation)
        {
            // Did not write completely.
            if (scheduleAsync)
            {
                SetState(StateFlags.WriteScheduled);
                bool pending;

#if NETCOREAPP || NETSTANDARD
                pending = Socket.SendAsync(operation);
#else
                if (ExecutionContext.IsFlowSuppressed())
                {
                    pending = Socket.SendAsync(operation);
                }
                else
                {
                    using (ExecutionContext.SuppressFlow())
                    {
                        pending = Socket.SendAsync(operation);
                    }
                }
#endif

                if (!pending)
                {
                    Unsafe.FinishWrite(operation); // ## 苦竹 修改 ## ((ISocketChannelUnsafe)this.Unsafe).FinishWrite(operation);
                }

                return(pending);
            }
            else
            {
                // Schedule flush again later so other tasks can be picked up input the meantime
                EventLoop.Execute(FlushAction, this);

                return(true);
            }
        }