docs: @Override
      protected boolean performRequest() {
          VirtualConnection vci = null;
          boolean completeOperation = true;
          TCPBaseRequestContext req = null;
          SelectionKey selectedKey = null;
  
          // If we were woken up because we have work to do, do it.
          Set<SelectionKey> keySet = selector.selectedKeys();
          Iterator<SelectionKey> selectedIterator = keySet.iterator();
          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
              Tr.debug(this, tc, "performRequest - processing " + keySet.size() + " items");
          }
          while (selectedIterator.hasNext()) {
              selectedKey = selectedIterator.next();
              // safely remove from set while looping
              selectedIterator.remove();
              req = (TCPBaseRequestContext) selectedKey.attachment();
              vci = req.getTCPConnLink().getVirtualConnection();
              completeOperation = true;
  
              // looking at the vci is messy here, but we're doing the try, catch
              // to save synchronization logic. vci could be null if connection
              // is closing before we can asked to request permission to finish
              // the read.
              if (vci == null) {
                  completeOperation = false;
              } else {
                  // only check if operation was an async read/write request
                  if (vci.isInputStateTrackingOperational() && !req.blockedThread) {
                      completeOperation = false;
                      if (req.isRequestTypeRead()) {
                          if (vci.requestPermissionToFinishRead()) {
                              completeOperation = true;
                          }
                      } else {
                          if (vci.requestPermissionToFinishWrite()) {
                              completeOperation = true;
                          }
                      }
                  }
              }
  
              if (completeOperation) {
                  // try to dispatch request. if it fails, just leave key alone,
                  // and it should get selected and tried again the next time through
                  // the selector.
                  if (wqm.dispatch(req, null)) {
                      // Dispatch worked, so set key's interest set to empty, so it isn't
                      // re-selected
                      // until the user asks us to do more work.
                      try {
                          selectedKey.interestOps(0);
                      } catch (CancelledKeyException cke) {
                          // ignore, since we already got the key and the data
                      }
                  }
              } else {
                  // permission denied, assume close has been processed on this VC
                  // therefore disregard this read.
                  if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
                      Tr.event(this, tc, "IO cancelled on closed key " + selectedKey);
                  }
                  try {
                      selectedKey.interestOps(0);
                  } catch (CancelledKeyException cke) {
                      // ignore, since the vc is closed/ing
                  }
              }
          }
  
          return false;
      }