diff --git a/test/regress.c b/test/regress.c index 0f4a6876..3afe2e66 100644 --- a/test/regress.c +++ b/test/regress.c @@ -549,6 +549,71 @@ test_persistent_timeout(void) event_del(&ev); } +struct persist_active_timeout_called { + int n; + short events[16]; + struct timeval tvs[16]; +}; + +static void +activate_cb(int fd, short event, void *arg) +{ + struct event *ev = arg; + event_active(ev, EV_READ, 1); +} + +static void +persist_active_timeout_cb(int fd, short event, void *arg) +{ + struct persist_active_timeout_called *c = arg; + if (c->n < 15) { + c->events[c->n] = event; + evutil_gettimeofday(&c->tvs[c->n], NULL); + ++c->n; + } +} + +static void +test_persistent_active_timeout(void *ptr) +{ + struct timeval tv, tv2, tv_exit, start; + struct event ev; + struct persist_active_timeout_called res; + + struct basic_test_data *data = ptr; + struct event_base *base = data->base; + + memset(&res, 0, sizeof(res)); + + tv.tv_sec = 0; + tv.tv_usec = 200 * 1000; + event_assign(&ev, base, -1, EV_TIMEOUT|EV_PERSIST, + persist_active_timeout_cb, &res); + event_add(&ev, &tv); + + tv2.tv_sec = 0; + tv2.tv_usec = 100 * 1000; + event_base_once(base, -1, EV_TIMEOUT, activate_cb, &ev, &tv2); + + tv_exit.tv_sec = 0; + tv_exit.tv_usec = 600 * 1000; + event_base_loopexit(base, &tv_exit); + + evutil_gettimeofday(&start, NULL); + + event_base_dispatch(base); + + tt_int_op(res.n, ==, 3); + tt_int_op(res.events[0], ==, EV_READ); + tt_int_op(res.events[1], ==, EV_TIMEOUT); + tt_int_op(res.events[2], ==, EV_TIMEOUT); + test_timeval_diff_eq(&start, &res.tvs[0], 100); + test_timeval_diff_eq(&start, &res.tvs[1], 300); + test_timeval_diff_eq(&start, &res.tvs[2], 500); +end: + ; +} + static int total_common_counts; struct common_timeout_info { @@ -2006,6 +2071,8 @@ struct testcase_t main_testcases[] = { /* These are still using the old API */ LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE), + { "persistent_active_timeout", test_persistent_active_timeout, + TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, LEGACY(priorities, TT_FORK|TT_NEED_BASE), { "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE, &basic_setup, NULL }, diff --git a/test/regress.h b/test/regress.h index 6ebff89e..8a20225c 100644 --- a/test/regress.h +++ b/test/regress.h @@ -90,6 +90,7 @@ void run_legacy_test_fn(void *ptr); /* All the flags that a legacy test needs. */ #define TT_ISOLATED TT_FORK|TT_NEED_SOCKETPAIR|TT_NEED_BASE + #define BASIC(name,flags) \ { #name, test_## name, flags, &basic_setup, NULL } @@ -108,6 +109,10 @@ int _test_ai_eq(const struct evutil_addrinfo *ai, const char *sockaddr_port, goto end; \ } while(0) +#define test_timeval_diff_eq(tv1, tv2, diff) \ + tt_int_op(abs(timeval_msec_diff((tv1), (tv2)) - diff), <=, 30) + +long timeval_msec_diff(const struct timeval *start, const struct timeval *end); #ifdef __cplusplus } diff --git a/test/regress_main.c b/test/regress_main.c index 4e733e18..1ba73f2b 100644 --- a/test/regress_main.c +++ b/test/regress_main.c @@ -76,6 +76,15 @@ #include "tinytest_macros.h" #include "../iocp-internal.h" +long +timeval_msec_diff(const struct timeval *start, const struct timeval *end) +{ + long ms = end->tv_sec - start->tv_sec; + ms *= 1000; + ms += ((end->tv_usec - start->tv_usec)+500) / 1000; + return ms; + +} /* ============================================================ */ /* Code to wrap up old legacy test cases that used setup() and cleanup().