/**
  * Change the response code for this response. If not specified, the code will be a {@code 200}.
  * Setting the response code after the response headers have been transmitted has no effect.
  *
  * @param responseCode the new code
  * @throws IllegalStateException if a response or upgrade was already sent
  */
 public void setResponseCode(final int responseCode) {
   if (responseCode < 0 || responseCode > 999) {
     throw new IllegalArgumentException("Invalid response code");
   }
   int oldVal, newVal;
   do {
     oldVal = state;
     if (allAreSet(oldVal, FLAG_RESPONSE_SENT)) {
       throw UndertowMessages.MESSAGES.responseAlreadyStarted();
     }
     newVal = oldVal & ~MASK_RESPONSE_CODE | responseCode & MASK_RESPONSE_CODE;
   } while (!stateUpdater.compareAndSet(this, oldVal, newVal));
 }
  /**
   * Transmit the response headers. After this method successfully returns, the response channel may
   * become writable.
   *
   * <p>If this method fails the request and response channels will be closed.
   *
   * <p>This method runs asynchronously. If the channel is writable it will attempt to write as much
   * of the response header as possible, and then queue the rest in a listener and return.
   *
   * <p>If future handlers in the chain attempt to write before this is finished XNIO will just
   * magically sort it out so it works. This is not actually implemented yet, so we just terminate
   * the connection straight away at the moment.
   *
   * <p>TODO: make this work properly
   *
   * @throws IllegalStateException if the response headers were already sent
   */
  void startResponse() throws IllegalStateException {
    int oldVal, newVal;
    do {
      oldVal = state;
      if (allAreSet(oldVal, FLAG_RESPONSE_SENT)) {
        throw UndertowMessages.MESSAGES.responseAlreadyStarted();
      }
      newVal = oldVal | FLAG_RESPONSE_SENT;
    } while (!stateUpdater.compareAndSet(this, oldVal, newVal));

    log.tracef(
        "Starting to write response for %s using channel %s", this, underlyingResponseChannel);
    final HeaderMap responseHeaders = this.responseHeaders;
    responseHeaders.lock();
  }