docs: public <T extends Response> T sendrecv ( Request request, T response, Set<RequestParam> params ) throws IOException {
          if ( isDisconnected() && this.state != 5 ) {
              throw new TransportException("Transport is disconnected " + this.name);
          }
          try {
              long timeout = !params.contains(RequestParam.NO_TIMEOUT) ? getResponseTimeout(request) : 0;
  
              long firstKey = doSend(request, response, params, timeout);
  
              if ( Thread.currentThread() == this.thread ) {
                  // we are in the transport thread, ie. on idle disconnecting
                  // this is synchronous operation
                  // This does not handle compound requests
                  synchronized ( this.inLock ) {
                      Long peekKey = peekKey();
                      if ( peekKey == firstKey ) {
                          doRecv(response);
                          response.received();
                          return response;
                      }
                      doSkip(peekKey);
                  }
              }
  
              return waitForResponses(request, response, timeout);
          }
          catch ( IOException ioe ) {
              log.warn("sendrecv failed", ioe);
              try {
                  disconnect(true);
              }
              catch ( IOException ioe2 ) {
                  ioe.addSuppressed(ioe2);
                  log.info("disconnect failed", ioe2);
              }
              throw ioe;
          }
          catch ( InterruptedException ie ) {
              throw new TransportException(ie);
          }
          finally {
              Response curResp = response;
              Request curReq = request;
              while ( curResp != null ) {
                  this.response_map.remove(curResp.getMid());
                  Request next = curReq.getNext();
                  if ( next != null ) {
                      curReq = next;
                      curResp = next.getResponse();
                  }
                  else {
                      break;
                  }
              }
          }
      }