diff --git a/ChangeLog b/ChangeLog index f772e6e1..66778733 100644 --- a/ChangeLog +++ b/ChangeLog @@ -41,3 +41,8 @@ Changes in current version: o Rename the "class" field in evdns_server_request to dns_question_class, so that it won't break compilation under C++. Use a macro so that old code won't break. Mark the macro as deprecated. o Fix DNS unit tests so that having a DNS server with broken IPv6 support is no longer cause for aborting the unit tests. o Make event_base_free() succeed even if there are pending non-internal events on a base. This may still leak memory and fds, but at least it no longer crashes. + o Post-process the config.h file into a new, installed event-config.h file that we can install, and whose macros will be safe to include in header files. + o Remove the long-deprecated acconfig.h file. + o Do not require #include before #include . + o Add new evutil_timer* functions to wrap (or replace) the regular timeval manipulation functions. + diff --git a/Makefile.am b/Makefile.am index 35e01974..e59a2f73 100644 --- a/Makefile.am +++ b/Makefile.am @@ -64,6 +64,22 @@ SYS_INCLUDES = endif +BUILT_SOURCES = event-config.h + +event-config.h: config.h + echo '/* event-config.h' > $@ + echo ' * Generated by autoconf; post-processed by libevent.' >> $@ + echo ' * Do not edit this file.' >> $@ + echo ' * Do not rely on macros in this file existing in later versions.'>> $@ + echo ' */' >> $@ + echo '#ifndef _EVENT_CONFIG_H_' >> $@ + echo '#define _EVENT_CONFIG_H_' >> $@ + + sed -e 's/#define /#define _EVENT_/' \ + -e 's/#undef /#undef _EVENT_/' \ + -e 's/#ifndef /#ifndef _EVENT_/' < config.h >> $@ + echo "#endif" >> $@ + CORE_SRC = event.c buffer.c evbuffer.c log.c evutil.c $(SYS_SRC) EXTRA_SRC = event_tagging.c http.c evhttp.h http-internal.h evdns.c \ evdns.h evrpc.c evrpc.h evrpc-internal.h \ @@ -81,7 +97,7 @@ libevent_extra_la_SOURCES = $(EXTRA_SRC) libevent_extra_la_LIBADD = @LTLIBOBJS@ $(SYS_LIBS) libevent_extra_la_LDFLAGS = -release $(RELEASE) -version-info $(VERSION_INFO) -include_HEADERS = event.h evhttp.h evdns.h evrpc.h evutil.h +include_HEADERS = event.h evhttp.h evdns.h evrpc.h evutil.h event-config.h INCLUDES = -I$(srcdir)/compat $(SYS_INCLUDES) diff --git a/acconfig.h b/acconfig.h deleted file mode 100644 index 9cf4074f..00000000 --- a/acconfig.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Define if timeradd is defined in */ -#undef HAVE_TIMERADD -#ifndef HAVE_TIMERADD -#undef timersub -#define timeradd(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ - if ((vvp)->tv_usec >= 1000000) { \ - (vvp)->tv_sec++; \ - (vvp)->tv_usec -= 1000000; \ - } \ - } while (0) -#define timersub(tvp, uvp, vvp) \ - do { \ - (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ - (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ - if ((vvp)->tv_usec < 0) { \ - (vvp)->tv_sec--; \ - (vvp)->tv_usec += 1000000; \ - } \ - } while (0) -#endif /* !HAVE_TIMERADD */ - -#undef HAVE_TIMERCLEAR -#ifndef HAVE_TIMERCLEAR -#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 -#endif - -#undef HAVE_TIMERCMP -#ifndef HAVE_TIMERCMP -#undef timercmp -#define timercmp(tvp, uvp, cmp) \ - (((tvp)->tv_sec == (uvp)->tv_sec) ? \ - ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ - ((tvp)->tv_sec cmp (uvp)->tv_sec)) -#endif - -#undef HAVE_TIMERISSET -#ifndef HAVE_TIMERISSET -#undef timerisset -#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) -#endif - -/* Define if TAILQ_FOREACH is defined in */ -#undef HAVE_TAILQFOREACH -#ifndef HAVE_TAILQFOREACH -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_FOREACH(var, head, field) \ - for((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT(var, field)) -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) -#endif /* TAILQ_FOREACH */ - diff --git a/evbuffer.c b/evbuffer.c index 52712bce..f968bb5a 100644 --- a/evbuffer.c +++ b/evbuffer.c @@ -43,6 +43,7 @@ #include #endif +#include "evutil.h" #include "event.h" /* prototypes */ @@ -56,7 +57,7 @@ bufferevent_add(struct event *ev, int timeout) struct timeval tv, *ptv = NULL; if (timeout) { - timerclear(&tv); + evutil_timerclear(&tv); tv.tv_sec = timeout; ptv = &tv; } diff --git a/event-internal.h b/event-internal.h index 432c0889..de9c7879 100644 --- a/event-internal.h +++ b/event-internal.h @@ -31,6 +31,7 @@ extern "C" { #endif +#include "config.h" #include "min_heap.h" #include "evsignal.h" @@ -55,6 +56,23 @@ struct event_base { struct min_heap timeheap; }; +/* Internal use only: Functions that might be missing from */ +#ifndef HAVE_TAILQFOREACH +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_FOREACH(var, head, field) \ + for((var) = TAILQ_FIRST(head); \ + (var) != TAILQ_END(head); \ + (var) = TAILQ_NEXT(var, field)) +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) +#endif /* TAILQ_FOREACH */ + #ifdef __cplusplus } #endif diff --git a/event.c b/event.c index fb94691b..a800e8f0 100644 --- a/event.c +++ b/event.c @@ -54,6 +54,7 @@ #include "event.h" #include "event-internal.h" +#include "evutil.h" #include "log.h" #ifdef HAVE_EVENT_PORTS @@ -415,7 +416,7 @@ event_base_loop(struct event_base *base, int flags) * if we have active events, we just poll new events * without waiting. */ - timerclear(&tv); + evutil_timerclear(&tv); } /* If we have no events, we just exit */ @@ -493,7 +494,7 @@ event_base_once(struct event_base *base, int fd, short events, if (events == EV_TIMEOUT) { if (tv == NULL) { - timerclear(&etv); + evutil_timerclear(&etv); tv = &etv; } @@ -597,10 +598,10 @@ event_pending(struct event *ev, short event, struct timeval *tv) /* See if there is a timeout that we should report */ if (tv != NULL && (flags & event & EV_TIMEOUT)) { gettime(&now); - timersub(&ev->ev_timeout, &now, &res); + evutil_timersub(&ev->ev_timeout, &now, &res); /* correctly remap to real time */ gettimeofday(&now, NULL); - timeradd(&now, &res, tv); + evutil_timeradd(&now, &res, tv); } return (flags & event); @@ -649,7 +650,7 @@ event_add(struct event *ev, struct timeval *tv) } gettime(&now); - timeradd(&now, tv, &ev->ev_timeout); + evutil_timeradd(&now, tv, &ev->ev_timeout); event_debug(( "event_add: timeout in %d seconds, call %p", @@ -747,12 +748,12 @@ timeout_next(struct event_base *base, struct timeval **tv_p) if (gettime(&now) == -1) return (-1); - if (timercmp(&ev->ev_timeout, &now, <=)) { - timerclear(tv); + if (evutil_timercmp(&ev->ev_timeout, &now, <=)) { + evutil_timerclear(tv); return (0); } - timersub(&ev->ev_timeout, &now, tv); + evutil_timersub(&ev->ev_timeout, &now, tv); assert(tv->tv_sec >= 0); assert(tv->tv_usec >= 0); @@ -779,14 +780,14 @@ timeout_correct(struct event_base *base, struct timeval *tv) /* Check if time is running backwards */ gettime(tv); - if (timercmp(tv, &base->event_tv, >=)) { + if (evutil_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); + evutil_timersub(&base->event_tv, tv, &off); /* * We can modify the key element of the node without destroying @@ -796,7 +797,7 @@ timeout_correct(struct event_base *base, struct timeval *tv) size = base->timeheap.n; for (; size-- > 0; ++pev) { struct timeval *tv = &(**pev).ev_timeout; - timersub(tv, &off, tv); + evutil_timersub(tv, &off, tv); } } @@ -812,7 +813,7 @@ timeout_process(struct event_base *base) gettime(&now); while ((ev = min_heap_top(&base->timeheap))) { - if (timercmp(&ev->ev_timeout, &now, >)) + if (evutil_timercmp(&ev->ev_timeout, &now, >)) break; event_queue_remove(base, ev, EVLIST_TIMEOUT); diff --git a/event.h b/event.h index 8087bdb1..6d9c3db9 100644 --- a/event.h +++ b/event.h @@ -159,6 +159,10 @@ extern "C" { #endif +#include +#ifdef _EVENT_HAVE_SYS_TYPES_H +#include +#endif #include #include #include diff --git a/evrpc.c b/evrpc.c index d7f6fb0b..63378326 100644 --- a/evrpc.c +++ b/evrpc.c @@ -60,6 +60,7 @@ #include "evrpc.h" #include "evrpc-internal.h" #include "evhttp.h" +#include "evutil.h" #include "log.h" struct evrpc_base * @@ -533,7 +534,7 @@ evrpc_schedule_request(struct evhttp_connection *connection, * a timeout after which the whole rpc is going to be aborted. */ struct timeval tv; - timerclear(&tv); + evutil_timerclear(&tv); tv.tv_sec = pool->timeout; evtimer_add(&ctx->ev_timeout, &tv); } diff --git a/evutil.h b/evutil.h index 358c8199..ca57e6ce 100644 --- a/evutil.h +++ b/evutil.h @@ -38,6 +38,11 @@ extern "C" { #endif +#include +#ifdef _EVENT_HAVE_SYS_TIME_H +#include +#endif + int evutil_socketpair(int d, int type, int protocol, int sv[2]); int evutil_make_socket_nonblocking(int sock); #ifdef WIN32 @@ -56,6 +61,54 @@ int evutil_make_socket_nonblocking(int sock); do { errno = (errcode); } while (0) #endif +/* + * Manipulation functions for struct timeval + */ +#ifdef _EVENT_HAVE_TIMERADD +#define evutil_timeradd(tvp, uvp, vvp) timeradd((tvp), (uvp), (vvp)) +#define evutil_timersub(tvp, uvp, vvp) timersub((tvp), (uvp), (vvp)) +#else +#define evutil_timeradd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#define evutil_timersub(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ + (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) +#endif /* !_EVENT_HAVE_HAVE_TIMERADD */ + +#ifdef _EVENT_HAVE_TIMERCLEAR +#define evutil_timerclear(tvp) timerclear(tvp) +#else +#define evutil_timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif + +#ifdef _EVENT_HAVE_TIMERCMP +#define evutil_timercmp(tvp, uvp, cmp) timercmp((tvp), (uvp), cmp) +#else +#define evutil_timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#endif + +#ifdef _EVENT_HAVE_TIMERISSET +#define evutil_timerisset(tvp) timerisset(tvp) +#else +#define evutil_timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#endif + #ifdef __cplusplus } #endif diff --git a/http.c b/http.c index 9415c934..fcaab41f 100644 --- a/http.c +++ b/http.c @@ -255,7 +255,7 @@ evhttp_add_event(struct event *ev, int timeout, int default_timeout) if (timeout != 0) { struct timeval tv; - timerclear(&tv); + evutil_timerclear(&tv); tv.tv_sec = timeout != -1 ? timeout : default_timeout; event_add(ev, &tv); } else { diff --git a/sample/time-test.c b/sample/time-test.c index 073d6ff1..aba4f623 100644 --- a/sample/time-test.c +++ b/sample/time-test.c @@ -25,6 +25,7 @@ #include #include +#include int lasttime; @@ -39,7 +40,7 @@ timeout_cb(int fd, short event, void *arg) newtime - lasttime); lasttime = newtime; - timerclear(&tv); + evutil_timerclear(&tv); tv.tv_sec = 2; event_add(timeout, &tv); } @@ -56,7 +57,7 @@ main (int argc, char **argv) /* Initalize one event */ evtimer_set(&timeout, timeout_cb, &timeout); - timerclear(&tv); + evutil_timerclear(&tv); tv.tv_sec = 2; event_add(&timeout, &tv); diff --git a/test/bench.c b/test/bench.c index ed32ae06..28c31beb 100644 --- a/test/bench.c +++ b/test/bench.c @@ -114,7 +114,7 @@ run_once(void) if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count); } - timersub(&te, &ts, &te); + evutil_timersub(&te, &ts, &te); return (&te); } diff --git a/test/regress.c b/test/regress.c index e098f61c..a95f7d6a 100644 --- a/test/regress.c +++ b/test/regress.c @@ -178,10 +178,10 @@ timeout_cb(int fd, short event, void *arg) int diff; gettimeofday(&tcalled, NULL); - if (timercmp(&tcalled, &tset, >)) - timersub(&tcalled, &tset, &tv); + if (evutil_timercmp(&tcalled, &tset, >)) + evutil_timersub(&tcalled, &tset, &tv); else - timersub(&tset, &tcalled, &tv); + evutil_timersub(&tset, &tcalled, &tv); diff = tv.tv_sec*1000 + tv.tv_usec/1000 - SECONDS * 1000; if (diff < 0) @@ -593,7 +593,7 @@ test_loopexit(void) gettimeofday(&tv_start, NULL); event_dispatch(); gettimeofday(&tv_end, NULL); - timersub(&tv_end, &tv_start, &tv_end); + evutil_timersub(&tv_end, &tv_start, &tv_end); evtimer_del(&ev); @@ -746,7 +746,7 @@ test_priorities_cb(int fd, short what, void *arg) pri->count++; - timerclear(&tv); + evutil_timerclear(&tv); event_add(&pri->ev, &tv); } @@ -777,7 +777,7 @@ test_priorities(int npriorities) exit(1); } - timerclear(&tv); + evutil_timerclear(&tv); if (event_add(&one.ev, &tv) == -1) exit(1); @@ -869,7 +869,7 @@ test_want_only_once(void) write(pair[0], TEST1, strlen(TEST1)+1); /* Setup the loop termination */ - timerclear(&tv); + evutil_timerclear(&tv); tv.tv_sec = 1; event_loopexit(&tv); @@ -950,7 +950,7 @@ evtag_fuzz(void) /* Now insert some corruption into the tag length field */ evbuffer_drain(tmp, -1); - timerclear(&tv); + evutil_timerclear(&tv); tv.tv_sec = 1; evtag_marshal_timeval(tmp, 0, &tv); evbuffer_add(tmp, buffer, sizeof(buffer)); @@ -1026,7 +1026,7 @@ rpc_test(void) } gettimeofday(&tv_end, NULL); - timersub(&tv_end, &tv_start, &tv_end); + evutil_timersub(&tv_end, &tv_start, &tv_end); fprintf(stderr, "(%.1f us/add) ", (float)tv_end.tv_sec/(float)i * 1000000.0 + tv_end.tv_usec / (float)i);