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
This commit is contained in:
Nick Mathewson 2007-11-07 06:01:57 +00:00
parent d0ce7d4ed7
commit f74e7258fd
13 changed files with 128 additions and 90 deletions

View File

@ -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 <sys/types.h> before #include <event.h>.
o Add new evutil_timer* functions to wrap (or replace) the regular timeval manipulation functions.

View File

@ -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)

View File

@ -1,62 +0,0 @@
/* Define if timeradd is defined in <sys/time.h> */
#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 <sys/queue.h> */
#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 */

View File

@ -43,6 +43,7 @@
#include <stdarg.h>
#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;
}

View File

@ -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 <sys/queue.h> */
#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

25
event.c
View File

@ -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);

View File

@ -159,6 +159,10 @@
extern "C" {
#endif
#include <event-config.h>
#ifdef _EVENT_HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <sys/time.h>
#include <stdint.h>
#include <stdarg.h>

View File

@ -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);
}

View File

@ -38,6 +38,11 @@
extern "C" {
#endif
#include <event-config.h>
#ifdef _EVENT_HAVE_SYS_TIME_H
#include <sys/time.h>
#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

2
http.c
View File

@ -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 {

View File

@ -25,6 +25,7 @@
#include <errno.h>
#include <event.h>
#include <evutil.h>
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);

View File

@ -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);
}

View File

@ -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);