docs: @Override
      protected void checkForTimeouts() {
          final boolean bTrace = TraceComponent.isAnyTracingEnabled();
  
          // See if anything may have timed out
          final long now = super.currentTime;
          if (now < nextTimeoutTime) {
              if (bTrace && tc.isDebugEnabled()) {
                  Tr.debug(this, tc, "checkForTimeouts bypassing timeout processing");
              }
              return;
          }
  
          Set<SelectionKey> selectorKeys = selector.keys();
          if (bTrace && tc.isDebugEnabled()) {
              Tr.debug(this, tc, "checkForTimeouts - checking " + selectorKeys.size() + " keys for timeouts");
          }
          if (selectorKeys.isEmpty()) {
              // if this isn't the primary (first) selector, see if it should be closed
              if (countIndex > 0) {
                  // if we have already been waiting, and still no keys, and this
                  // isn't the primary selector, we should close this
                  if (waitingToQuit) {
                      quit = true;
                  } else {
                      wqm.updateCount(countIndex, WorkQueueManager.CS_DELETE_IN_PROGRESS, channelType);
                      waitingToQuit = true;
                      nextTimeoutTime = now + TCPFactoryConfiguration.getChannelSelectorWaitToTerminate();
                  }
              } else {
                  nextTimeoutTime = now + TCPFactoryConfiguration.getChannelSelectorIdleTimeout();
              }
          } else {
              waitingToQuit = false;
              // go through requests, timing out those that need it, and calculating new
              // timeout
              // set nexttimeouttime to whatever the selectoridletimeout is, and work
              // back from there
              nextTimeoutTime = now + TCPFactoryConfiguration.getChannelSelectorIdleTimeout();
              for (SelectionKey key : selectorKeys) {
                  try {
                      if (key.interestOps() <= 0) {
                          // skip if not waiting on read/writes
                          continue;
                      }
                      TCPBaseRequestContext req = (TCPBaseRequestContext) key.attachment();
                      if (!req.hasTimeout()) {
                          // skip if read/write does not have a timeout
                          continue;
                      }
                      if (req.getTimeoutTime() <= now) {
                          if (bTrace && tc.isEventEnabled()) {
                              Tr.event(this, tc, "Inactivity timeout on channel " + req.getTCPConnLink().getSocketIOChannel().getChannel());
                          }
  
                          // create timeout exception to pass to callback error method
                          // Add local and remote address information
                          String ioeMessage = "Socket operation timed out before it could be completed";
                          try {
                              SocketAddress iaLocal = req.getTCPConnLink().getSocketIOChannel().getSocket().getLocalSocketAddress();
                              SocketAddress iaRemote = req.getTCPConnLink().getSocketIOChannel().getSocket().getRemoteSocketAddress();
                              ioeMessage = ioeMessage + " local=" + iaLocal + " remote=" + iaRemote;
                          } catch (Exception x) {
                              // do not alter the message if the socket got nuked while we tried to look at it
                          }
                          IOException e = new SocketTimeoutException(ioeMessage);
  
                          if (wqm.dispatch(req, e)) {
                              // reset interest ops so selector won't fire again for this key
                              key.interestOps(0);
                          } else {
                              // try again in another second
                              nextTimeoutTime = now;
                          }
                      } else {
                          // adjust times for 1 second granularity of ApproxTime
                          if (req.getTimeoutTime() < nextTimeoutTime) {
                              nextTimeoutTime = req.getTimeoutTime();
                          }
                      }
                  } catch (CancelledKeyException cke) {
                      // either we didn't get the key, or we already dispatched the
                      // error. In either case, there is nothing more to do
                      continue;
                  }
              } // end-key-loop
          }
      }