mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-12 13:58:58 -04:00
Merge branch '20_periodic_event_overload_v2' into patches-2.0
This commit is contained in:
commit
03614a16cb
26
event.c
26
event.c
@ -1258,12 +1258,12 @@ event_persist_closure(struct event_base *base, struct event *ev)
|
||||
* ev_io_timeout after the last time it was _scheduled_ for,
|
||||
* not ev_io_timeout after _now_. If it fired for another
|
||||
* reason, though, the timeout ought to start ticking _now_. */
|
||||
struct timeval run_at;
|
||||
struct timeval run_at, relative_to, delay, now;
|
||||
ev_uint32_t usec_mask = 0;
|
||||
EVUTIL_ASSERT(is_same_common_timeout(&ev->ev_timeout,
|
||||
&ev->ev_io_timeout));
|
||||
gettime(base, &now);
|
||||
if (is_common_timeout(&ev->ev_timeout, base)) {
|
||||
ev_uint32_t usec_mask;
|
||||
struct timeval delay, relative_to;
|
||||
delay = ev->ev_io_timeout;
|
||||
usec_mask = delay.tv_usec & ~MICROSECONDS_MASK;
|
||||
delay.tv_usec &= MICROSECONDS_MASK;
|
||||
@ -1271,20 +1271,26 @@ event_persist_closure(struct event_base *base, struct event *ev)
|
||||
relative_to = ev->ev_timeout;
|
||||
relative_to.tv_usec &= MICROSECONDS_MASK;
|
||||
} else {
|
||||
gettime(base, &relative_to);
|
||||
relative_to = now;
|
||||
}
|
||||
evutil_timeradd(&relative_to, &delay, &run_at);
|
||||
run_at.tv_usec |= usec_mask;
|
||||
} else {
|
||||
struct timeval relative_to;
|
||||
delay = ev->ev_io_timeout;
|
||||
if (ev->ev_res & EV_TIMEOUT) {
|
||||
relative_to = ev->ev_timeout;
|
||||
} else {
|
||||
gettime(base, &relative_to);
|
||||
relative_to = now;
|
||||
}
|
||||
evutil_timeradd(&ev->ev_io_timeout, &relative_to,
|
||||
&run_at);
|
||||
}
|
||||
evutil_timeradd(&relative_to, &delay, &run_at);
|
||||
if (evutil_timercmp(&run_at, &now, <)) {
|
||||
/* Looks like we missed at least one invocation due to
|
||||
* a clock jump, not running the event loop for a
|
||||
* while, really slow callbacks, or
|
||||
* something. Reschedule relative to now.
|
||||
*/
|
||||
evutil_timeradd(&now, &delay, &run_at);
|
||||
}
|
||||
run_at.tv_usec |= usec_mask;
|
||||
event_add_internal(ev, &run_at, 1);
|
||||
}
|
||||
EVBASE_RELEASE_LOCK(base, th_base_lock);
|
||||
|
@ -627,6 +627,27 @@ test_persistent_timeout(void)
|
||||
event_del(&ev);
|
||||
}
|
||||
|
||||
static void
|
||||
test_persistent_timeout_jump(void *ptr)
|
||||
{
|
||||
struct basic_test_data *data = ptr;
|
||||
struct event ev;
|
||||
int count = 0;
|
||||
struct timeval msec100 = { 0, 100 * 1000 };
|
||||
struct timeval msec50 = { 0, 50 * 1000 };
|
||||
|
||||
event_assign(&ev, data->base, -1, EV_PERSIST, periodic_timeout_cb, &count);
|
||||
event_add(&ev, &msec100);
|
||||
/* Wait for a bit */
|
||||
sleep(1);
|
||||
event_base_loopexit(data->base, &msec50);
|
||||
event_base_dispatch(data->base);
|
||||
tt_int_op(count, ==, 1);
|
||||
|
||||
end:
|
||||
event_del(&ev);
|
||||
}
|
||||
|
||||
struct persist_active_timeout_called {
|
||||
int n;
|
||||
short events[16];
|
||||
@ -2338,8 +2359,8 @@ struct testcase_t main_testcases[] = {
|
||||
BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
|
||||
BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),
|
||||
|
||||
/* These are still using the old API */
|
||||
LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE),
|
||||
{ "persistent_timeout_jump", test_persistent_timeout_jump, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
{ "persistent_active_timeout", test_persistent_active_timeout,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
LEGACY(priorities, TT_FORK|TT_NEED_BASE),
|
||||
|
Loading…
x
Reference in New Issue
Block a user