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; } }
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); }
protected override void DoBind(EndPoint localAddress) { _localAddress = LocalChannelRegistry.Register(this, _localAddress, localAddress); _state = 1; }
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; } }