Example #1
0
void
notify_progress (uint64_t position, uint64_t total)
{
  struct timeval now_t;
  int64_t last_us, now_us, elapsed_us;

  gettimeofday (&now_t, NULL);

  /* Always send a notification at 100%.  This simplifies callers by
   * allowing them to 'finish' the progress bar at 100% without
   * needing special code.
   */
  if (count_progress > 0 && position == total) {
    notify_progress_no_ratelimit (position, total, &now_t);
    return;
  }

  /* Calculate time in microseconds since the last progress message
   * was sent out (or since the start of the call).
   */
  last_us =
    (int64_t) last_progress_t.tv_sec * 1000000 + last_progress_t.tv_usec;
  now_us = (int64_t) now_t.tv_sec * 1000000 + now_t.tv_usec;
  elapsed_us = now_us - last_us;

  /* Rate limit. */
  if ((count_progress == 0 && elapsed_us < NOTIFICATION_INITIAL_DELAY) ||
      (count_progress > 0 && elapsed_us < NOTIFICATION_PERIOD))
    return;

  notify_progress_no_ratelimit (position, total, &now_t);
}
Example #2
0
/* Generate progress notification messages in order to test progress bars. */
static char *
debug_progress (const char *subcmd, size_t argc, char *const *const argv)
{
  uint64_t secs, rate = 0;
  char *ret;

  if (argc < 1) {
  error:
    reply_with_error ("progress: expecting one or more args: time in seconds [, rate in microseconds]");
    return NULL;
  }

  if (sscanf (argv[0], "%" SCNu64, &secs) != 1)
    goto error;
  if (secs == 0 || secs > 1000000) { /* RHBZ#816839 */
    reply_with_error ("progress: argument is 0, less than 0, or too large");
    return NULL;
  }

  if (argc >= 2) {
    if (sscanf (argv[1], "%" SCNu64, &rate) != 1)
      goto error;
    if (rate == 0 || rate > 1000000) {
      reply_with_error ("progress: rate is 0 or too large");
      return NULL;
    }
  }

  /* Note the inner loops go to '<= limit' because we want to ensure
   * that the final 100% completed message is set.
   */
  if (rate == 0) {              /* Ordinary rate-limited progress messages. */
    uint64_t tsecs = secs * 10; /* 1/10ths of seconds */
    uint64_t i;

    for (i = 1; i <= tsecs; ++i) {
      usleep (100000);
      notify_progress (i, tsecs);
    }
  }
  else {                        /* Send messages at a given rate. */
    uint64_t usecs = secs * 1000000; /* microseconds */
    uint64_t i;
    struct timeval now;

    for (i = rate; i <= usecs; i += rate) {
      usleep (rate);
      gettimeofday (&now, NULL);
      notify_progress_no_ratelimit (i, usecs, &now);
    }
  }

  ret = strdup ("ok");
  if (ret == NULL) {
    reply_with_perror ("strdup");
    return NULL;
  }

  return ret;
}