@Override
  protected void resetTimeouts() {
    // The NIO connector uses the timeout configured on the wrapper in the
    // poller. Therefore, it needs to be reset once asycn processing has
    // finished.
    final KeyAttachment attach = (KeyAttachment) socketWrapper.getSocket().getAttachment(false);
    if (!error && attach != null && asyncStateMachine.isAsyncDispatching()) {
      long soTimeout = endpoint.getSoTimeout();

      // reset the timeout
      if (keepAliveTimeout > 0) {
        attach.setTimeout(keepAliveTimeout);
      } else {
        attach.setTimeout(soTimeout);
      }
    }
  }
  /**
   * Send an action to the connector.
   *
   * @param actionCode Type of the action
   * @param param Action parameter
   */
  @Override
  protected void actionInternal(ActionCode actionCode, Object param) {

    if (actionCode == ActionCode.ASYNC_COMPLETE) {
      if (asyncStateMachine.asyncComplete()) {
        ((NioEndpoint) endpoint)
            .processSocket(this.socketWrapper.getSocket(), SocketStatus.OPEN_READ, false);
      }

    } else if (actionCode == ActionCode.ASYNC_SETTIMEOUT) {
      if (param == null) return;
      long timeout = ((Long) param).longValue();
      final KeyAttachment ka = (KeyAttachment) socketWrapper.getSocket().getAttachment(false);
      ka.setTimeout(timeout);

    } else if (actionCode == ActionCode.ASYNC_DISPATCH) {
      if (asyncStateMachine.asyncDispatch()) {
        ((NioEndpoint) endpoint)
            .processSocket(this.socketWrapper.getSocket(), SocketStatus.OPEN_READ, true);
      }
    }
  }
  @Override
  protected void output(byte[] src, int offset, int length) throws IOException {
    ByteBuffer writeBuffer = socketWrapper.getSocket().getBufHandler().getWriteBuffer();

    writeBuffer.put(src, offset, length);

    writeBuffer.flip();

    KeyAttachment att = (KeyAttachment) socketWrapper.getSocket().getAttachment(false);
    if (att == null) throw new IOException("Key must be cancelled");
    long writeTimeout = att.getWriteTimeout();
    Selector selector = null;
    try {
      selector = pool.get();
    } catch (IOException x) {
      // ignore
    }
    try {
      pool.write(writeBuffer, socketWrapper.getSocket(), selector, writeTimeout, true);
    } finally {
      if (selector != null) pool.put(selector);
    }
    writeBuffer.clear();
  }