/**
   * Log an exception.
   *
   * @param exception
   */
  protected void handleException(Throwable exception) {
    if (endTime == 0) {
      endTime = System.currentTimeMillis();
    }

    Log.logger.log(Level.SEVERE, "Uncaught exception.", exception);
    status |= sERROR;
    ControlThread.signalShutdown();
    done = true;
  }
  /**
   * General implementation of the main body of a simple JMS primitive.
   *
   * @param paceable A paceable instance of WorkerThread.
   * @param listener If not null, this overrides the above method and the given object as an
   *     asynchronous listener.
   */
  protected void run(WorkerThread.Paceable paceable) {
    Log.logger.log(Level.INFO, "START");
    try {
      status = sCONNECTING;

      buildAMQPResources();
      status = sRUNNING;

      if (logEnabled) Log.logger.log(Level.FINE, "Entering client loop");

      if (startTime == 0) {
        startTime = System.currentTimeMillis();
      }

      pace(paceable);
      done = true;

    } catch (Throwable e) {
      handleException(e);
    } finally {
      if (done) {
        status = (status & sERROR) | sENDING;

        if (endTime == 0) endTime = System.currentTimeMillis();

        Log.logger.info("STOP");
        close();
        status = (status & sERROR) | sENDED;

        try {
          int wait = Config.parms.getInt("ss");
          if (wait < 0) wait = 1;

          Thread.sleep(1000 * wait);
        } catch (InterruptedException e) {
        }
        ControlThread.signalShutdown();
      }
    }
  }