From f2645f80c135b44a9e82f809662da4bef93e8726 Mon Sep 17 00:00:00 2001 From: Andrea Shepard Date: Wed, 19 Nov 2014 12:18:05 +0000 Subject: [PATCH] Implement new/free for struct evutil_monotonic_timer and export monotonic time functions --- event.c | 15 +++++++++++ evutil_time.c | 50 +++++++++++++++++++++++++++++++++++++ include/event2/event.h | 6 +++++ include/event2/util.h | 56 ++++++++++++++++++++++++++++++++++++++++++ time-internal.h | 3 --- 5 files changed, 127 insertions(+), 3 deletions(-) diff --git a/event.c b/event.c index d3e46011..2e4f64ea 100644 --- a/event.c +++ b/event.c @@ -993,6 +993,21 @@ done: return (res); } +/* Get the monotonic time for this event_base' timer */ +int +event_gettime_monotonic(struct event_base *base, struct timeval *tv) +{ + int rv = -1; + + if (base && tv) { + EVBASE_ACQUIRE_LOCK(base, th_base_lock); + rv = evutil_gettime_monotonic_(&(base->monotonic_timer), tv); + EVBASE_RELEASE_LOCK(base, th_base_lock); + } + + return rv; +} + const char ** event_get_supported_methods(void) { diff --git a/evutil_time.c b/evutil_time.c index e433043e..8f53c66b 100644 --- a/evutil_time.c +++ b/evutil_time.c @@ -54,6 +54,7 @@ #include "event2/util.h" #include "util-internal.h" #include "log-internal.h" +#include "mm-internal.h" #ifndef EVENT__HAVE_GETTIMEOFDAY /* No gettimeofday; this must be windows. */ @@ -160,6 +161,55 @@ adjust_monotonic_time(struct evutil_monotonic_timer *base, base->last_time = *tv; } +/* + Allocate a new struct evutil_monotonic_timer + */ +struct evutil_monotonic_timer * +evutil_monotonic_timer_new(void) +{ + struct evutil_monotonic_timer *p = NULL; + + p = mm_malloc(sizeof(*p)); + if (!p) goto done; + + memset(p, 0, sizeof(*p)); + + done: + return p; +} + +/* + Free a struct evutil_monotonic_timer + */ +void +evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer) +{ + if (timer) { + mm_free(timer); + } +} + +/* + Set up a struct evutil_monotonic_timer for initial use + */ +int +evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer, + int flags) +{ + return evutil_configure_monotonic_time_(timer, flags); +} + +/* + Query the current monotonic time + */ +int +evutil_gettime_monotonic(struct evutil_monotonic_timer *timer, + struct timeval *tp) +{ + return evutil_gettime_monotonic_(timer, tp); +} + + #if defined(HAVE_POSIX_MONOTONIC) /* ===== The POSIX clock_gettime() interface provides a few ways to get at a diff --git a/include/event2/event.h b/include/event2/event.h index 6e2b884d..6e0a4f04 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -396,6 +396,12 @@ const char *event_base_get_method(const struct event_base *); EVENT2_EXPORT_SYMBOL const char **event_get_supported_methods(void); +/** Query the current monotonic time from a the timer for a struct + * event_base. + */ +EVENT2_EXPORT_SYMBOL +int event_gettime_monotonic(struct event_base *base, struct timeval *tp); + /** @name event type flag diff --git a/include/event2/util.h b/include/event2/util.h index 62b94773..b152a4b4 100644 --- a/include/event2/util.h +++ b/include/event2/util.h @@ -292,6 +292,62 @@ extern "C" { #define evutil_socket_t int #endif +/** + * Structure to hold information about a monotonic timer + * + * Use this with evutil_configure_monotonic_time() and + * evutil_gettime_monotonic(). + * + * This is an opaque structure; you can allocate one using + * evutil_monotonic_timer_new(). + * + * @see evutil_monotonic_timer_new(), evutil_monotonic_timer_free(), + * evutil_configure_monotonic_time(), evutil_gettime_monotonic() + */ +struct evutil_monotonic_timer +#ifdef EVENT_IN_DOXYGEN_ +{/*Empty body so that doxygen will generate documentation here.*/} +#endif +; + +#define EV_MONOT_PRECISE 1 +#define EV_MONOT_FALLBACK 2 + +/** Allocate a new struct evutil_monotonic_timer for use with the + * evutil_configure_monotonic_time() and evutil_gettime_monotonic() + * functions. You must configure the timer with + * evutil_configure_monotonic_time() before using it. + */ +EVENT2_EXPORT_SYMBOL +struct evutil_monotonic_timer * evutil_monotonic_timer_new(void); + +/** Free a struct evutil_monotonic_timer that was allocated using + * evutil_monotonic_timer_new(). + */ +EVENT2_EXPORT_SYMBOL +void evutil_monotonic_timer_free(struct evutil_monotonic_timer *timer); + +/** Set up a struct evutil_monotonic_timer; flags can include + * EV_MONOT_PRECISE and EV_MONOT_FALLBACK. + */ +EVENT2_EXPORT_SYMBOL +int evutil_configure_monotonic_time(struct evutil_monotonic_timer *timer, + int flags); + +/** Query the current monotonic time from a struct evutil_monotonic_timer + * previously configured with evutil_configure_monotonic_time(). Monotonic + * time is guaranteed never to run in reverse, but is not necessarily epoch- + * based, or relative to any other definite point. Use it to make reliable + * measurements of elapsed time between events even when the system time + * may be changed. + * + * It is not safe to use this funtion on the same timer from multiple + * threads. + */ +EVENT2_EXPORT_SYMBOL +int evutil_gettime_monotonic(struct evutil_monotonic_timer *timer, + struct timeval *tp); + /** Create two new sockets that are connected to each other. On Unix, this simply calls socketpair(). On Windows, it uses the diff --git a/time-internal.h b/time-internal.h index daf20f47..2c584fa7 100644 --- a/time-internal.h +++ b/time-internal.h @@ -86,9 +86,6 @@ struct evutil_monotonic_timer { struct timeval last_time; }; -#define EV_MONOT_PRECISE 1 -#define EV_MONOT_FALLBACK 2 - int evutil_configure_monotonic_time_(struct evutil_monotonic_timer *mt, int flags); int evutil_gettime_monotonic_(struct evutil_monotonic_timer *mt, struct timeval *tv); -- 2.40.0