diff --git a/configure.in b/configure.in index d32378c1..42e17a73 100644 --- a/configure.in +++ b/configure.in @@ -117,7 +117,7 @@ AC_C_INLINE AC_HEADER_TIME dnl Checks for library functions. -AC_CHECK_FUNCS(gettimeofday vasprintf fcntl) +AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime) AC_REPLACE_FUNCS(strlcpy) AC_MSG_CHECKING(for F_SETFD in fcntl.h) diff --git a/event.c b/event.c index 82df1bed..cbbb4bfb 100644 --- a/event.c +++ b/event.c @@ -138,6 +138,23 @@ compare(struct event *a, struct event *b) return (0); } +static int +gettime(struct timeval *tp) +{ +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1) + return (-1); + tp->tv_sec = ts.tv_sec; + tp->tv_usec = ts.tv_nsec / 1000; +#else + gettimeofday(tp, NULL); +#endif + + return (0); +} + RB_PROTOTYPE(event_tree, event, ev_timeout_node, compare); RB_GENERATE(event_tree, event, ev_timeout_node, compare); @@ -153,7 +170,7 @@ event_init(void) event_sigcb = NULL; event_gotsig = 0; - gettimeofday(¤t_base->event_tv, NULL); + gettime(¤t_base->event_tv); RB_INIT(¤t_base->timetree); TAILQ_INIT(¤t_base->eventqueue); @@ -341,7 +358,7 @@ event_base_loop(struct event_base *base, int flags) } /* Check if time is running backwards */ - gettimeofday(&tv, NULL); + gettime(&tv); if (timercmp(&tv, &base->event_tv, <)) { struct timeval off; event_debug(("%s: time is running backwards, corrected", @@ -499,6 +516,7 @@ event_priority_set(struct event *ev, int pri) int event_pending(struct event *ev, short event, struct timeval *tv) { + struct timeval now, res; int flags = 0; if (ev->ev_flags & EVLIST_INSERTED) @@ -513,8 +531,12 @@ event_pending(struct event *ev, short event, struct timeval *tv) event &= (EV_TIMEOUT|EV_READ|EV_WRITE|EV_SIGNAL); /* See if there is a timeout that we should report */ - if (tv != NULL && (flags & event & EV_TIMEOUT)) - *tv = ev->ev_timeout; + if (tv != NULL && (flags & event & EV_TIMEOUT)) { + gettime(&now); + timersub(&ev->ev_timeout, &now, &res); + gettime(&now); + timeradd(&now, &res, tv); + } return (flags & event); } @@ -558,7 +580,7 @@ event_add(struct event *ev, struct timeval *tv) event_queue_remove(base, ev, EVLIST_ACTIVE); } - gettimeofday(&now, NULL); + gettime(&now); timeradd(&now, tv, &ev->ev_timeout); event_debug(( @@ -654,7 +676,7 @@ timeout_next(struct event_base *base, struct timeval *tv) return (0); } - if (gettimeofday(&now, NULL) == -1) + if (gettime(&now) == -1) return (-1); if (timercmp(&ev->ev_timeout, &now, <=)) { @@ -690,7 +712,7 @@ timeout_process(struct event_base *base) struct timeval now; struct event *ev, *next; - gettimeofday(&now, NULL); + gettime(&now); for (ev = RB_MIN(event_tree, &base->timetree); ev; ev = next) { if (timercmp(&ev->ev_timeout, &now, >))