예제 #1
0
 protected override void DoClose()
 {
     if (_state <= 1)
     {
         // Update all internal state before the CloseTask is notified
         if (_localAddress != null)
         {
             LocalChannelRegistry.Unregister(_localAddress);
             _localAddress = null;
         }
         _state = 2;
     }
 }
예제 #2
0
            public override Task ConnectAsync(EndPoint remoteAddress, EndPoint localAddress)
            {
                if (Local._state == State.Connected)
                {
                    var cause = new AlreadyConnectedException();
                    Local.Pipeline.FireExceptionCaught(cause);
                    return(TaskEx.FromException(cause));
                }

                if (Local._connectPromise != null)
                {
                    throw new ConnectionPendingException();
                }

                Local._connectPromise = new TaskCompletionSource();
                if (Local._state != State.Bound)
                {
                    // Not bound yet and no LocalAddress specified. Get one
                    if (localAddress == null)
                    {
                        localAddress = new LocalAddress(Local);
                    }
                }

                if (localAddress != null)
                {
                    try
                    {
                        Local.DoBind(localAddress);
                    }
                    catch (Exception ex)
                    {
                        PromiseUtil.SafeSetFailure(Local._connectPromise, ex, Logger);
                        return(CloseAsync());
                    }
                }

                var boundChannel = LocalChannelRegistry.Get(remoteAddress);

                if (!(boundChannel is LocalServerChannel))
                {
                    var cause = new ChannelException("connection refused");
                    PromiseUtil.SafeSetFailure(Local._connectPromise, cause, Logger);
                    return(CloseAsync());
                }

                var serverChannel = boundChannel as LocalServerChannel;

                Local._peer = serverChannel.Serve(Local);
                return(TaskEx.Completed);
            }
예제 #3
0
 protected override void DoBind(EndPoint localAddress)
 {
     _localAddress = LocalChannelRegistry.Register(this, _localAddress, localAddress);
     _state        = 1;
 }
예제 #4
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;
            }
        }