상속: AbstractChannel
예제 #1
0
        private void FinishPeerRead0(LocalChannel peer)
        {
            var finishPeerReadTask = peer._finishReadTask;

            if (finishPeerReadTask != null)
            {
                if (!finishPeerReadTask.IsCompleted)
                {
                    RunFinishPeerReadTask(peer);
                    return;
                }
                // TODO: might need to make this lazy in order to avoid a premature unset while scheduling a new task
                peer._finishReadTask = null;
            }

            var peerPipeline = peer.Pipeline;

            if (peer._readInProgress)
            {
                peer._readInProgress = false;
                while (true)
                {
                    if (peer._inboundBuffer.Count == 0)
                    {
                        break;
                    }
                    var received = peer._inboundBuffer.Dequeue();
                    peerPipeline.FireChannelRead(received);
                }
                peerPipeline.FireChannelReadComplete();
            }
        }
예제 #2
0
 private void DoPeerClose(LocalChannel peer, bool peerWriteInProgress)
 {
     if (peerWriteInProgress)
     {
         FinishPeerRead0(peer);
     }
     peer.Unsafe.CloseAsync();
 }
예제 #3
0
        public LocalChannel(LocalServerChannel parent, LocalChannel peer) : base(parent)
        {
            _peer          = peer;
            _localAddress  = parent.LocalAddress;
            _remoteAddress = peer.LocalAddress;

            Configuration = new DefaultChannelConfiguration(this);
            _shutdownHook = new ShutdownHook(this);
            _readTask     = new ReadTask(this);
        }
예제 #4
0
        public LocalChannel(LocalServerChannel parent, LocalChannel peer) : base(parent)
        {
            _peer = peer;
            _localAddress = parent.LocalAddress;
            _remoteAddress = peer.LocalAddress;

            Configuration = new DefaultChannelConfiguration(this);
            _shutdownHook = new ShutdownHook(this);
            _readTask = new ReadTask(this);
        }
예제 #5
0
 private void FinishPeerRead(LocalChannel peer)
 {
     // If the peer is also writing, then we must schedule the event on the event loop to preserve read order.
     if (peer.EventLoop == EventLoop && !peer._writeInProgress)
     {
         FinishPeerRead0(peer);
     }
     else
     {
         RunFinishPeerReadTask(peer);
     }
 }
예제 #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
 private void RunFinishPeerReadTask(LocalChannel peer)
 {
     try
     {
         if (peer._writeInProgress)
         {
             peer._finishReadTask = _peer.EventLoop.SubmitAsync(DoFinishPeerReadAsync, this, peer);
         }
         else
         {
             peer.EventLoop.Execute(DoFinishPeerRead, this, peer);
         }
     }
     catch (Exception)
     {
         _peer.ReleaseInboundBuffers();
         throw;
     }
 }
예제 #8
0
 private void Serve0(LocalChannel child)
 {
     _inboundBuffer.Enqueue(child);
     if (_acceptInProgress)
     {
         _acceptInProgress = false;
         var pipeline = Pipeline;
         while (true)
         {
             if (_inboundBuffer.Count == 0)
             {
                 break;
             }
             var m = _inboundBuffer.Dequeue();
             pipeline.FireChannelRead(m);
         }
         pipeline.FireChannelReadComplete();
     }
 }
예제 #9
0
 public ShutdownHook(LocalChannel channel)
 {
     _channel = channel;
 }
예제 #10
0
        private void FinishPeerRead0(LocalChannel peer)
        {
            var finishPeerReadTask = peer._finishReadTask;
            if (finishPeerReadTask != null)
            {
                if (!finishPeerReadTask.IsCompleted)
                {
                    RunFinishPeerReadTask(peer);
                    return;
                }
                // TODO: might need to make this lazy in order to avoid a premature unset while scheduling a new task
                peer._finishReadTask = null;
            }

            var peerPipeline = peer.Pipeline;
            if (peer._readInProgress)
            {
                peer._readInProgress = false;
                while (true)
                {
                    if (peer._inboundBuffer.Count == 0)
                    {
                        break;
                    }
                    var received = peer._inboundBuffer.Dequeue();
                    peerPipeline.FireChannelRead(received);
                }
                peerPipeline.FireChannelReadComplete();
            }
        }
예제 #11
0
 public ReadTask(LocalChannel channel)
 {
     _channel = channel;
 }
예제 #12
0
 private void FinishPeerRead(LocalChannel peer)
 {
     // If the peer is also writing, then we must schedule the event on the event loop to preserve read order.
     if (peer.EventLoop == EventLoop && !peer._writeInProgress)
     {
         FinishPeerRead0(peer);
     }
     else
     {
         RunFinishPeerReadTask(peer);
     }
 }
예제 #13
0
 private void RunFinishPeerReadTask(LocalChannel peer)
 {
     try
     {
         if (peer._writeInProgress)
         {
             peer._finishReadTask = _peer.EventLoop.SubmitAsync(DoFinishPeerReadAsync, this, peer);
         }
         else
         {
             peer.EventLoop.Execute(DoFinishPeerRead, this, peer);
         }
     }
     catch (Exception)
     {
         _peer.ReleaseInboundBuffers();
         throw;
     }
 }
예제 #14
0
        protected override void DoClose()
        {
            var peer = _peer;
            if (_state != State.Closed)
            {
                // Update all internal state before the CloseTask is notified
                if (_localAddress != null)
                {
                    if (Parent == null)
                    {
                        LocalChannelRegistry.Unregister(_localAddress);
                    }
                    _localAddress = null;
                }

                // State change must happen before finishPeerRead to ensure writes are released either in doWrite or
                // channelRead.
                _state = State.Closed;

                var promise = _connectPromise;
                if (promise != null)
                {
                    promise.TrySetException(ClosedChannelException.Instance);
                    _connectPromise = null;
                }

                // To preserve ordering of events we must process any pending reads
                if (_writeInProgress && peer != null)
                {
                    FinishPeerRead(peer);
                }
            }

            if (peer != null && peer.IsActive)
            {
                if (peer.EventLoop.InEventLoop && !_registerInProgress)
                {
                    DoPeerClose(peer, peer._writeInProgress);
                }
                else
                {
                    // This value may change, and so we should save it before executing the IRunnable
                    var peerWriteInProgress = peer._writeInProgress;
                    try
                    {
                        peer.EventLoop.Execute((context, state) => // todo: allocation
                        {
                            var p = (LocalChannel) context;
                            var wIP = (bool) state;
                            DoPeerClose(p, wIP);
                        }, peer, peerWriteInProgress);
                    }
                    catch (Exception ex)
                    {
                        // The peer close may attempt to drain this._inboundBuffers. If that fails make sure it is drained.
                        ReleaseInboundBuffers();
                        throw;
                    }
                }

                _peer = null;
            }
        }
예제 #15
0
 private void DoPeerClose(LocalChannel peer, bool peerWriteInProgress)
 {
     if (peerWriteInProgress)
     {
         FinishPeerRead0(peer);
     }
     peer.Unsafe.CloseAsync();
 }
예제 #16
0
 private void Serve0(LocalChannel child)
 {
     _inboundBuffer.Enqueue(child);
     if (_acceptInProgress)
     {
         _acceptInProgress = false;
         var pipeline = Pipeline;
         while (true)
         {
             if (_inboundBuffer.Count == 0)
                 break;
             var m = _inboundBuffer.Dequeue();
             pipeline.FireChannelRead(m);
         }
         pipeline.FireChannelReadComplete();
     }
 }
예제 #17
0
 public ReadTask(LocalChannel channel)
 {
     _channel = channel;
 }
예제 #18
0
 public LocalUnsafe(LocalChannel channel) : base(channel)
 {
     Local = channel;
 }
예제 #19
0
 public ShutdownHook(LocalChannel channel)
 {
     _channel = channel;
 }
예제 #20
0
 public LocalUnsafe(LocalChannel channel) : base(channel)
 {
     Local = channel;
 }
예제 #21
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;
 }
예제 #22
0
        protected override void DoClose()
        {
            var peer = _peer;

            if (_state != State.Closed)
            {
                // Update all internal state before the CloseTask is notified
                if (_localAddress != null)
                {
                    if (Parent == null)
                    {
                        LocalChannelRegistry.Unregister(_localAddress);
                    }
                    _localAddress = null;
                }

                // State change must happen before finishPeerRead to ensure writes are released either in doWrite or
                // channelRead.
                _state = State.Closed;

                var promise = _connectPromise;
                if (promise != null)
                {
                    promise.TrySetException(ClosedChannelException.Instance);
                    _connectPromise = null;
                }

                // To preserve ordering of events we must process any pending reads
                if (_writeInProgress && peer != null)
                {
                    FinishPeerRead(peer);
                }
            }

            if (peer != null && peer.IsActive)
            {
                if (peer.EventLoop.InEventLoop && !_registerInProgress)
                {
                    DoPeerClose(peer, peer._writeInProgress);
                }
                else
                {
                    // This value may change, and so we should save it before executing the IRunnable
                    var peerWriteInProgress = peer._writeInProgress;
                    try
                    {
                        peer.EventLoop.Execute((context, state) => // todo: allocation
                        {
                            var p   = (LocalChannel)context;
                            var wIP = (bool)state;
                            DoPeerClose(p, wIP);
                        }, peer, peerWriteInProgress);
                    }
                    catch (Exception ex)
                    {
                        // The peer close may attempt to drain this._inboundBuffers. If that fails make sure it is drained.
                        ReleaseInboundBuffers();
                        throw;
                    }
                }

                _peer = null;
            }
        }