From: Nick Mathewson Date: Wed, 7 Nov 2007 06:01:57 +0000 (+0000) Subject: r16501@catbus: nickm | 2007-11-07 01:00:31 -0500 X-Git-Tag: release-2.0.1-alpha~523 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f74e7258fd29a341b4ecf08dfdb83e50aaee3255;p=libevent r16501@catbus: nickm | 2007-11-07 01:00:31 -0500 This is one of those patches which will either make matters far simpler after the bugs shake out, or will get reverted pretty quick once we realize that it is a stupid idea. We now post-process the config.h file into a new event-config.h file, whose macros are prefixed with _EVENT_ and which is thus safe for headers to include. Using this, we can define replacement timeval manipulation functions in evutil.h, and use them uniformly through our code. We can also detect which headers are needful in event.h, and include them as required. This is also the perfect time to remove the long-deprecated acconfig.h file, so that autoheader no longer warns. Should resolve the following issues: [ 1826530 ] Header files should have access to autoconf output. [ 1826545 ] acconfig.h is deprecated. [ 1826564 ] On some platforms, event.h can't be included alone. svn:r492 --- 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);