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; } }
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; } }