diff options
| author | William Ahern <[email protected]> | 2016-02-26 22:21:35 -0800 |
|---|---|---|
| committer | William Ahern <[email protected]> | 2016-02-26 22:21:35 -0800 |
| commit | 43a854241b93a85929785b37f45e133bd880690c (patch) | |
| tree | 0e4e141ad71a649913c4de9fb68947c1dc27c432 | |
| parent | a8a62b4f356f6c67ead7bcbd1ecb8202c4f6af6f (diff) | |
| parent | d6b1d96614572cc414949e176bdc67a4af8d6682 (diff) | |
Merge branch 'fixing_intervals' of git://github.com/nmathewson/timeout into nmathewson-fixing_intervals
| -rw-r--r-- | test-timeout.c | 36 | ||||
| -rw-r--r-- | timeout.c | 19 |
2 files changed, 37 insertions, 18 deletions
diff --git a/test-timeout.c b/test-timeout.c index 47582e0..4607958 100644 --- a/test-timeout.c +++ b/test-timeout.c @@ -226,6 +226,7 @@ struct intervals_cfg { int n_timeouts; timeout_t start_at; timeout_t end_at; + timeout_t skip; }; int @@ -261,23 +262,35 @@ check_intervals(struct intervals_cfg *cfg) while (now < cfg->end_at) { timeout_t delay = timeouts_timeout(tos); + if (cfg->skip && delay < cfg->skip) + delay = cfg->skip; timeouts_step(tos, delay); - now += delay; while (NULL != (to = timeouts_get(tos))) { i = to - &t[0]; assert(&t[i] == to); fired[i]++; + if (0 != (to->expires - cfg->start_at) % cfg->timeouts[i]) + FAIL(); + if (to->expires <= now) + FAIL(); + if (to->expires > now + cfg->timeouts[i]) + FAIL(); } if (!timeouts_check(tos, stderr)) FAIL(); } - timeout_t duration = cfg->end_at - cfg->start_at; + timeout_t duration = now - cfg->start_at; for (i = 0; i < cfg->n_timeouts; ++i) { - if (fired[i] != duration / cfg->timeouts[i]) - FAIL(); + if (cfg->skip) { + if (fired[i] > duration / cfg->timeouts[i]) + FAIL(); + } else { + if (fired[i] != duration / cfg->timeouts[i]) + FAIL(); + } if (!timeout_pending(&t[i])) FAIL(); } @@ -420,25 +433,36 @@ main(int argc, char **argv) .n_timeouts = sizeof(primes)/sizeof(timeout_t), .start_at = 50, .end_at = 5322, + .skip = 0, }; DO(check_intervals(&icfg1)); struct intervals_cfg icfg2 = { - .timeouts = primes, + .timeouts = factors_of_1337, .n_timeouts = sizeof(factors_of_1337)/sizeof(timeout_t), .start_at = 50, .end_at = 50000, + .skip = 0, }; DO(check_intervals(&icfg2)); struct intervals_cfg icfg3 = { - .timeouts = primes, + .timeouts = multiples_of_five, .n_timeouts = sizeof(multiples_of_five)/sizeof(timeout_t), .start_at = 49, .end_at = 5333, + .skip = 0, }; DO(check_intervals(&icfg3)); + struct intervals_cfg icfg4 = { + .timeouts = primes, + .n_timeouts = sizeof(primes)/sizeof(timeout_t), + .start_at = 50, + .end_at = 5322, + .skip = 16, + }; + DO(check_intervals(&icfg4)); if (n_failed) { puts("\nFAIL"); @@ -358,18 +358,13 @@ static void timeouts_readd(struct timeouts *T, struct timeout *to) { to->expires += to->interval; if (to->expires <= T->curtime) { - if (to->expires < T->curtime) { - timeout_t n = T->curtime - to->expires; - timeout_t q = n / to->interval; - timeout_t r = n % to->interval; - - if (r) - to->expires += (to->interval * q) + (to->interval - r); - else - to->expires += (to->interval * q); - } else { - to->expires += to->interval; - } + /* If we've missed the next firing of this timeout, reschedule + * it to occur at the next multiple of its interval after + * the last time that it fired. + */ + timeout_t n = T->curtime - to->expires; + timeout_t r = n % to->interval; + to->expires = T->curtime + (to->interval - r); } timeouts_sched(T, to, to->expires); |
