docs: protected IOResult attemptReadFromSocket(TCPBaseRequestContext readReq, boolean fromSelector) throws IOException {
  
          IOResult rc = IOResult.NOT_COMPLETE;
          TCPReadRequestContextImpl req = (TCPReadRequestContextImpl) readReq;
          TCPConnLink conn = req.getTCPConnLink();
  
          long dataRead = 0;
  
          if (req.getJITAllocateSize() > 0 && req.getBuffers() == null) {
              // User wants us to allocate the buffer
              if (conn.getConfig().getAllocateBuffersDirect()) {
                  req.setBuffer(ChannelFrameworkFactory.getBufferManager().allocateDirect(req.getJITAllocateSize()));
              } else {
                  req.setBuffer(ChannelFrameworkFactory.getBufferManager().allocate(req.getJITAllocateSize()));
              }
              req.setJITAllocateAction(true);
          }
  
          WsByteBuffer wsBuffArray[] = req.getBuffers();
  
          dataRead = attemptReadFromSocketUsingNIO(req, wsBuffArray);
  
          req.setLastIOAmt(dataRead);
          req.setIODoneAmount(req.getIODoneAmount() + dataRead);
          if (req.getIODoneAmount() >= req.getIOAmount()) {
              rc = IOResult.COMPLETE;
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
              Tr.event(this, tc, "Read " + dataRead + "(" + +req.getIODoneAmount() + ")" + " bytes, " + req.getIOAmount() + " requested on local: "
                                 + getSocket().getLocalSocketAddress()
                                 + " remote: " + getSocket().getRemoteSocketAddress());
          }
  
          // when request came from selector, it should always read at least 1 byte
          // if it does read 0 (saw this 1 time), just let it retry
  
          if (req.getLastIOAmt() < 0) {
              // read did not find any data, though the read key was selected
              if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled() && !conn.getConfig().isInbound()) {
                  Tr.event(this, tc, "Empty read on outbound.");
              }
              if (req.getJITAllocateAction()) {
                  req.getBuffer().release();
                  req.setBuffer(null);
                  req.setJITAllocateAction(false);
              }
              return IOResult.FAILED;
          }
  
          if (rc == IOResult.COMPLETE) {
              req.setIOCompleteAmount(req.getIODoneAmount());
              req.setIODoneAmount(0);
          } else if (rc == IOResult.NOT_COMPLETE && !fromSelector && req.getJITAllocateAction() && req.getLastIOAmt() == 0) {
              // Did not read any data on immediate read, so release
              // the buffers used for the jitallocation so that
              // we will re-allocate them again later.
              req.getBuffer().release();
              req.setBuffers(null);
              req.setJITAllocateAction(true);
          }
          return rc;
      }