docs: synchronized public ModbusResponse processRequest(ModbusRequest request) throws ModbusProtocolException, ModbusIOException {
          try {
              sendRequest(request);
              if (request.getServerAddress() != Modbus.BROADCAST_ID) {
                  do {
                      try {
                          ModbusResponse msg = (ModbusResponse) readResponse(request);
                          request.validateResponse(msg);
                          /*
                           * if you have received an ACKNOWLEDGE,
                           * it means that operation is in processing and you should be waiting for the answer
                           */
                          if (msg.getModbusExceptionCode() != ModbusExceptionCode.ACKNOWLEDGE) {
                              if (msg.isException())
                                  throw new ModbusProtocolException(msg.getModbusExceptionCode());
                              return msg;
                          }
                      } catch (ModbusNumberException mne) {
                          Modbus.log().warning(mne.getLocalizedMessage());
                      }
                  } while (System.currentTimeMillis() - requestTime < getConnection().getReadTimeout());
                  /*
                   * throw an exception if there is a response timeout
                   */
                  throw new ModbusIOException("Response timeout.");
              } else {
              /*
               return because slaves do not respond broadcast requests
               */
                  broadcastResponse.setFunction(request.getFunction());
                  return broadcastResponse;
              }
          } catch (ModbusIOException mioe) {
              disconnect();
              throw mioe;
          }
      }