@Override
  public void exchangeEvent(
      final HttpServerExchange exchange,
      final ExchangeCompletionListener.NextListener nextListener) {
    connection.resetChannel();
    final HttpServerConnection connection = this.connection;
    if (exchange.isPersistent() && !exchange.isUpgrade()) {
      newRequest();
      StreamConnection channel = connection.getChannel();
      if (connection.getExtraBytes() == null) {
        // if we are not pipelining we just register a listener

        channel.getSourceChannel().getReadSetter().set(this);
        channel.getSourceChannel().resumeReads();
      } else {
        if (channel.getSourceChannel().isReadResumed()) {
          channel.getSourceChannel().suspendReads();
        }
        if (exchange.isInIoThread()) {
          channel.getIoThread().execute(this);
        } else {
          Executor executor = exchange.getDispatchExecutor();
          if (executor == null) {
            executor = exchange.getConnection().getWorker();
          }
          executor.execute(this);
        }
      }
    }
    nextListener.proceed();
  }
 @Override
 public void run() {
   handle = null;
   if (expireTime == -1) {
     return;
   }
   long current = System.currentTimeMillis();
   if (current < expireTime) {
     // timeout has been bumped, re-schedule
     handle =
         WorkerUtils.executeAfter(
             connection.getIoThread(),
             timeoutCommand,
             (expireTime - current) + FUZZ_FACTOR,
             TimeUnit.MILLISECONDS);
     return;
   }
   UndertowLogger.REQUEST_LOGGER.tracef(
       "Timing out channel %s due to inactivity", connection.getSourceChannel());
   IoUtils.safeClose(connection);
   if (connection.getSourceChannel().isReadResumed()) {
     ChannelListeners.invokeChannelListener(
         connection.getSourceChannel(), connection.getSourceChannel().getReadListener());
   }
   if (connection.getSinkChannel().isWriteResumed()) {
     ChannelListeners.invokeChannelListener(
         connection.getSinkChannel(), connection.getSinkChannel().getWriteListener());
   }
 }
 /**
  * Construct a new instance.
  *
  * @param delegate the underlying connection
  */
 UndertowSslConnection(StreamConnection delegate, SSLEngine engine, ByteBufferPool bufferPool) {
   super(delegate.getIoThread());
   this.delegate = delegate;
   this.engine = engine;
   sslConduit = new SslConduit(this, delegate, engine, bufferPool, new HandshakeCallback());
   setSourceConduit(sslConduit);
   setSinkConduit(sslConduit);
 }
 private void handleResumeTimeout() {
   Integer timeout = getTimeout();
   if (timeout == null || timeout <= 0) {
     return;
   }
   long currentTime = System.currentTimeMillis();
   expireTime = currentTime + timeout;
   XnioExecutor.Key key = handle;
   if (key == null) {
     handle =
         connection.getIoThread().executeAfter(timeoutCommand, timeout, TimeUnit.MILLISECONDS);
   }
 }
 @Override
 public XnioIoThread getIoThread() {
   return channel.getIoThread();
 }
 @Override
 public XnioIoThread getIoThread() {
   return connection.getIoThread();
 }