support for periodic timeouts

svn:r762
This commit is contained in:
Niels Provos 2008-05-03 22:10:09 +00:00
parent 8c750eaff8
commit 1d30750b1d
5 changed files with 79 additions and 0 deletions

View File

@ -87,6 +87,7 @@ Changes in current version:
o introduce evbuffer_reserve_space() and evbuffer_commit_space() to make processing in filters more efficient. o introduce evbuffer_reserve_space() and evbuffer_commit_space() to make processing in filters more efficient.
o reduce system calls for getting current time by caching it. o reduce system calls for getting current time by caching it.
o separate signal events from io events; making the code less complex. o separate signal events from io events; making the code less complex.
o support for periodic timeouts
Changes in 1.4.0: Changes in 1.4.0:
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr. o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.

18
event.c
View File

@ -137,6 +137,7 @@ static void timeout_process(struct event_base *);
static void timeout_correct(struct event_base *, struct timeval *); static void timeout_correct(struct event_base *, struct timeval *);
static void event_signal_closure(struct event_base *, struct event *ev); static void event_signal_closure(struct event_base *, struct event *ev);
static void event_periodic_closure(struct event_base *, struct event *ev);
static void static void
detect_monotonic(void) detect_monotonic(void)
@ -362,6 +363,13 @@ event_haveevents(struct event_base *base)
return (base->event_count > 0); return (base->event_count > 0);
} }
static void
event_periodic_closure(struct event_base *base, struct event *ev)
{
event_add(ev, &ev->_ev.ev_periodic.tv_interval);
(*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg);
}
static void static void
event_signal_closure(struct event_base *base, struct event *ev) event_signal_closure(struct event_base *base, struct event *ev)
{ {
@ -709,6 +717,16 @@ event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, shor
return (0); return (0);
} }
void
evperiodic_assign(struct event *ev, struct event_base *base,
struct timeval *tv, void (*cb)(evutil_socket_t, short, void *), void *arg)
{
event_assign(ev, base, -1, EV_TIMEOUT, cb, arg);
ev->_ev.ev_periodic.tv_interval = *tv;
ev->ev_closure = event_periodic_closure;
}
struct event * struct event *
event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg) event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg)
{ {

View File

@ -184,6 +184,22 @@ int event_base_loopexit(struct event_base *, struct timeval *);
*/ */
int event_base_loopbreak(struct event_base *); int event_base_loopbreak(struct event_base *);
/**
Define a periodic timer.
Behaves like a timer only that it repeats at the specified interval.
To start this time, it needs to be added via event_add().
@param ev event struct to be modified
@param base the event base to which this event belongs
@param tv periodicity interval
@param cb callback function
@param arg argument that will be passed to the callback function
*/
void evperiodic_assign(struct event *ev, struct event_base *base,
struct timeval *tv, void (*cb)(int, short, void *), void *arg);
/** /**
Define a timer event. Define a timer event.

View File

@ -104,6 +104,10 @@ struct event {
/* Allows deletes in callback */ /* Allows deletes in callback */
short *ev_pncalls; short *ev_pncalls;
} ev_signal; } ev_signal;
struct {
struct timeval tv_interval;
} ev_periodic;
} _ev; } _ev;
short ev_events; short ev_events;

View File

@ -432,6 +432,43 @@ test_simpletimeout(void)
cleanup_test(); cleanup_test();
} }
static void
periodic_timeout_cb(int fd, short event, void *arg)
{
int *count = arg;
(*count)++;
if (*count > 5) {
test_ok = 1;
event_base_loopexit(global_base, NULL);
}
}
static void
test_periodictimeout(void)
{
struct timeval tv, tv_interval;
struct event ev;
int count = 0;
setup_test("Periodic timeout: ");
timerclear(&tv_interval);
tv_interval.tv_usec = 10000;
tv.tv_usec = 0;
tv.tv_sec = 0;
evperiodic_assign(&ev, global_base, &tv_interval,
periodic_timeout_cb, &count);
event_add(&ev, &tv);
event_dispatch();
event_del(&ev);
cleanup_test();
}
#ifndef WIN32 #ifndef WIN32
extern struct event_base *current_base; extern struct event_base *current_base;
static void static void
@ -2044,6 +2081,8 @@ main (int argc, char **argv)
test_evutil_strtoll(); test_evutil_strtoll();
test_periodictimeout();
/* use the global event base and need to be called first */ /* use the global event base and need to be called first */
test_priorities(1); test_priorities(1);
test_priorities(2); test_priorities(2);
@ -2091,6 +2130,7 @@ main (int argc, char **argv)
test_combined(); test_combined();
test_simpletimeout(); test_simpletimeout();
#ifndef WIN32 #ifndef WIN32
test_simplesignal(); test_simplesignal();
test_immediatesignal(); test_immediatesignal();