libevent contains a fallback path in case clock_gettime(CLOCK_MONOTONIC)
fails. The fallback path tries to cope with time going backwards and
reaches into the timeheap internals, as noticed by Tobias in
https://marc.info/?l=openbsd-tech&m=155595247719664&w=2
I doubt that we care about this kind of seldom-tested compat code, which
was probably useful to get portable libevent to run on various
(ancient?) systems.
Our clock_gettime can only fail for two reasons:
- invalid clock id. Lots of our userland uses CLOCK_MONOTONIC now,
I think it can be considered a requirement.
- invalid timespec pointer. Here, since we pass the address of
a timespec structure on the stack something must be really wrong if we
get EFAULT.
So the diff below removes the fallback path and all associated code and
variables. I have left out some minor cleanups for now to ease reviews.
Thoughts/oks?
Index: event.c
===================================================================
--- event.c.orig
+++ event.c
@@ -62,7 +62,6 @@ static const struct eventop *eventops[]
/* Global state */
struct event_base *current_base = NULL;
extern struct event_base *evsignal_base;
-static int use_monotonic;
/* Handle signals - This is a deprecated interface */
int (*event_sigcb)(void); /* Signal callback when gotsig is set */
@@ -77,37 +76,24 @@ static void event_process_active(struct
static int timeout_next(struct event_base *, struct timeval **);
static void timeout_process(struct event_base *);
-static void timeout_correct(struct event_base *, struct timeval *);
-
-static void
-detect_monotonic(void)
-{
- struct timespec ts;
-
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
- use_monotonic = 1;
-}
static int
gettime(struct event_base *base, struct timeval *tp)
{
+ struct timespec ts;
+
if (base->tv_cache.tv_sec) {
*tp = base->tv_cache;
return (0);
}
- if (use_monotonic) {
- struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
+ event_err(1, "libevent: clock_gettime failed");
- if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
- return (-1);
-
- tp->tv_sec = ts.tv_sec;
- tp->tv_usec = ts.tv_nsec / 1000;
- return (0);
- }
+ tp->tv_sec = ts.tv_sec;
+ tp->tv_usec = ts.tv_nsec / 1000;
- return (gettimeofday(tp, NULL));
+ return (0);
}
struct event_base *
@@ -133,7 +119,6 @@ event_base_new(void)
event_sigcb = NULL;
event_gotsig = 0;
- detect_monotonic();
gettime(base, &base->event_tv);
min_heap_ctor(&base->timeheap);
@@ -466,8 +451,6 @@ event_base_loop(struct event_base *base,
}
}
- timeout_correct(base, &tv);
-
tv_p = &tv;
if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) {
timeout_next(base, &tv_p);
@@ -837,47 +820,6 @@ timeout_next(struct event_base *base, st
return (0);
}
-/*
- * Determines if the time is running backwards by comparing the current
- * time against the last time we checked. Not needed when using clock
- * monotonic.
- */
-
-static void
-timeout_correct(struct event_base *base, struct timeval *tv)
-{
- struct event **pev;
- size_t size;
- struct timeval off;
-
- if (use_monotonic)
- return;
-
- /* Check if time is running backwards */
- gettime(base, tv);
- if (timercmp(tv, &base->event_tv, >=)) {
- base->event_tv = *tv;
- return;
- }
-
- event_debug(("%s: time is running backwards, corrected",
- __func__));
- timersub(&base->event_tv, tv, &off);
-
- /*
- * We can modify the key element of the node without destroying
- * the key, beause we apply it to all in the right order.
- */
- pev = base->timeheap.p;
- size = base->timeheap.n;
- for (; size-- > 0; ++pev) {
- struct timeval *ev_tv = &(**pev).ev_timeout;
- timersub(ev_tv, &off, ev_tv);
- }
- /* Now remember what the new time turned out to be. */
- base->event_tv = *tv;
-}
-
void
timeout_process(struct event_base *base)
{
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE