private void terminate(Throwable cause) { while (true) { CloseState current = closed.get(); switch (current) { case NOT_CLOSED: case LOCALLY_CLOSED: case REMOTELY_CLOSED: { if (closed.compareAndSet(current, CloseState.CLOSED)) { flusher.terminate(cause); for (IStream stream : streams.values()) stream.close(); streams.clear(); disconnect(); return; } break; } default: { return; } } } }