示例#1
0
/**
 * As tor_gettimeofday_cached, but can never move backwards in time.
 *
 * The returned value may diverge from wall-clock time, since wall-clock time
 * can trivially be adjusted backwards, and this can't.  Don't mix wall-clock
 * time with these values in the same calculation.
 *
 * Depending on implementation, this function may or may not "smooth out" huge
 * jumps forward in wall-clock time.  It may or may not keep its results
 * advancing forward (as opposed to stalling) if the wall-clock time goes
 * backwards.  The current implementation does neither of of these.
 *
 * This function is not thread-safe; do not call it outside the main thread.
 *
 * In future versions of Tor, this may return a time does not have its
 * origin at the Unix epoch.
 */
void
tor_gettimeofday_cached_monotonic(struct timeval *tv)
{
  struct timeval last_tv = { 0, 0 };

  tor_gettimeofday_cached(tv);
  if (timercmp(tv, &last_tv, OP_LT)) {
    memcpy(tv, &last_tv, sizeof(struct timeval));
  } else {
    memcpy(&last_tv, tv, sizeof(struct timeval));
  }
}
示例#2
0
/**
 * Process scheduled callbacks up to current time.
 *
 * @return The number of milliseconds untill the next scheduled event
 * or -1 for no event.
 */
int 
schedule_run(void)
{
	struct timeval tv;
	struct timeval nexttime;
	struct timeval rettime;
        struct nscallback *cur_nscb;
        struct nscallback *prev_nscb;
        struct nscallback *unlnk_nscb;

        if (schedule_list == NULL)
                return -1;

	/* reset enumeration to the start of the list */
        cur_nscb = schedule_list;
        prev_nscb = NULL;
	nexttime = cur_nscb->tv;

	gettimeofday(&tv, NULL);

        while (cur_nscb != NULL) {
                if (timercmp(&tv, &cur_nscb->tv, 0)) {
                        /* scheduled time */

                        /* remove callback */
                        unlnk_nscb = cur_nscb;

                        if (prev_nscb == NULL) {
                                schedule_list = unlnk_nscb->next;
                        } else {
                                prev_nscb->next = unlnk_nscb->next;
                        }

                        unlnk_nscb->callback(unlnk_nscb->p);

                        free(unlnk_nscb);
			
                        /* need to deal with callback modifying the list. */
			if (schedule_list == NULL)
				return -1; /* no more callbacks scheduled */
			
                        /* reset enumeration to the start of the list */
                        cur_nscb = schedule_list;
                        prev_nscb = NULL;
			nexttime = cur_nscb->tv;
                } else {
			/* if the time to the event is sooner than the
			 * currently recorded soonest event record it 
			 */
			if (timercmp(&nexttime, &cur_nscb->tv, 0)) {
				nexttime = cur_nscb->tv;
			}
                        /* move to next element */
                        prev_nscb = cur_nscb;
                        cur_nscb = prev_nscb->next;
                }
        }

	/* make rettime relative to now */
	timersub(&nexttime, &tv, &rettime);

	/*LOG(("returning time to next event as %ldms",(rettime.tv_sec * 1000) + (rettime.tv_usec / 1000))); */
	/* return next event time in milliseconds (24days max wait) */
        return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
}