private void readProcessorLoop() {
    boolean check_high_first = true;

    while (true) {
      loop_count++;
      try {
        if (check_high_first) {
          check_high_first = false;
          if (!doHighPriorityRead()) {
            if (!doNormalPriorityRead()) {
              if (read_waiter.waitForEvent(hasConnections() ? IDLE_SLEEP_TIME : 1000)) {
                wait_count++;
              }
            }
          }
        } else {
          check_high_first = true;
          if (!doNormalPriorityRead()) {
            if (!doHighPriorityRead()) {
              if (read_waiter.waitForEvent(hasConnections() ? IDLE_SLEEP_TIME : 1000)) {
                wait_count++;
              }
            }
          }
        }
      } catch (Throwable t) {
        Debug.out("readProcessorLoop() EXCEPTION: ", t);
      }
    }
  }
  /**
   * Add the given entity to the controller for read processing.
   *
   * @param entity to process reads for
   */
  public void addReadEntity(RateControlledEntity entity) {
    try {
      entities_mon.enter();
      if (entity.getPriority() == RateControlledEntity.PRIORITY_HIGH) {
        // copy-on-write
        ArrayList<RateControlledEntity> high_new =
            new ArrayList<RateControlledEntity>(high_priority_entities.size() + 1);
        high_new.addAll(high_priority_entities);
        high_new.add(entity);
        high_priority_entities = high_new;
      } else {
        // copy-on-write
        ArrayList<RateControlledEntity> norm_new =
            new ArrayList<RateControlledEntity>(normal_priority_entities.size() + 1);
        norm_new.addAll(normal_priority_entities);
        norm_new.add(entity);
        normal_priority_entities = norm_new;
      }

      entity_count = normal_priority_entities.size() + high_priority_entities.size();
    } finally {
      entities_mon.exit();
    }

    read_waiter.eventOccurred();
  }
  private boolean doRead(RateControlledEntity ready_entity) {
    if (ready_entity != null) {

      if (AGGRESIVE_READ) {

        // skip over failed readers to find a good one

        if (ready_entity.doProcessing(read_waiter, 0) > 0) {

          progress_count++;

          return (true);

        } else {

          non_progress_count++;

          if (entity_check_count - last_entity_check_count
              >= normal_priority_entities.size() + high_priority_entities.size()) {

            last_entity_check_count = entity_check_count;

            // force a wait

            if (read_waiter.waitForEvent(IDLE_SLEEP_TIME)) {
              wait_count++;
            }

            return (false);
          }

          return (true);
        }
      } else {

        return (ready_entity.doProcessing(read_waiter, 0) > 0);
      }
    }

    return false;
  }