/**
   * The body of this thread contains an endless (under certain assertions) loop. Each iteration is
   * performed once after previous thread's iteration has finished.
   */
  @Override
  public void run() {
    log.debug("Started thread.");
    try {
      while (isAlive) {
        // preparing
        loopy.runPreUnLock();

        try {
          waitForRelease();
        } catch (InterruptedException e) {
          log.debug("Thread interrupted.");
        }

        // executing body:
        loopy.runBody();

        // releasing next thread:
        getParentChain().releaseNext(this);

        // postprocessing
        loopy.runPostLock();
      }
    } catch (Error e) {
      // uncaught errors for debug:
      log.error("General error.", e);
      super.getParentChain().reportGeneralError(this, e);
    }

    log.debug("Thread is stopped.");
  }
  @Override
  public void start() {
    thread.start();

    loopy.start();
  }