From: Nick Mathewson Date: Tue, 27 Oct 2009 04:25:45 +0000 (+0000) Subject: Give event_assign a return value, and make it less inclined to exit(). X-Git-Tag: release-2.0.3-alpha~75 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e9ee1057e63b33d833b83b404232a0ccde34ae56;p=libevent Give event_assign a return value, and make it less inclined to exit(). We also refactor event_assign so that it is the core function, and event_set() is only the wrapper. svn:r1469 --- diff --git a/ChangeLog b/ChangeLog index 878ac8fe..cef1fda7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -34,6 +34,7 @@ Changes in 2.0.3-alpha: o Stop using enums as arguments or return values when what we mean is a bitfield of enum values. C++ doesn't believe that you can OR two enum values together and get another enum, and C++ takes its typing seriously. Patch from Christopher Davis. o Add an API to replace all fatal calls to exit() with a user-provided panic function. o Replace all assert() calls with a variant that is aware of the user-provided logging and panic functions. + o Add a return value to event_assign so that it can fail rather than asserting when the user gives it bad input. event_set still dies on bad input. Changes in 2.0.2-alpha: diff --git a/event.c b/event.c index c484c758..d82c7c6e 100644 --- a/event.c +++ b/event.c @@ -1038,9 +1038,8 @@ event_base_once(struct event_base *base, evutil_socket_t fd, short events, return (0); } -void -event_set(struct event *ev, evutil_socket_t fd, short events, - void (*callback)(evutil_socket_t, short, void *), void *arg) +int +event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg) { /* Take the current base - caller needs to set the real base later */ ev->ev_base = current_base; @@ -1055,9 +1054,11 @@ event_set(struct event *ev, evutil_socket_t fd, short events, ev->ev_pncalls = NULL; if (events & EV_SIGNAL) { - if ((events & (EV_READ|EV_WRITE)) != 0) - event_errx(1, "%s: EV_SIGNAL incompatible use", - __func__); + if ((events & (EV_READ|EV_WRITE)) != 0) { + event_warnx("%s: EV_SIGNAL is not compatible with " + "EV_READ or EV_WRITE", __func__); + return -1; + } ev->ev_closure = EV_CLOSURE_SIGNAL; } else { if (events & EV_PERSIST) { @@ -1070,9 +1071,16 @@ event_set(struct event *ev, evutil_socket_t fd, short events, min_heap_elem_init(ev); - /* by default, we put new events into the middle priority */ - if (current_base) - ev->ev_pri = current_base->nactivequeues/2; + if (base != NULL) { + if (event_base_set(base, ev) < 0) { + event_warnx("%s: event_base_set() failed", __func__); + return -1; + } + } else if (current_base) { + /* by default, we put new events into the middle priority */ + ev->ev_pri = current_base->nactivequeues/2; + } + return 0; } int @@ -1089,11 +1097,12 @@ event_base_set(struct event_base *base, struct event *ev) } void -event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg) +event_set(struct event *ev, evutil_socket_t fd, short events, + void (*callback)(evutil_socket_t, short, void *), void *arg) { - event_set(ev, fd, events, cb, arg); - if (base != NULL) - EVUTIL_ASSERT(event_base_set(base, ev) == 0); + int r; + r = event_assign(ev, NULL, fd, events, callback, arg); + EVUTIL_ASSERT(r == 0); } struct event * @@ -1103,7 +1112,10 @@ event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)( ev = mm_malloc(sizeof(struct event)); if (ev == NULL) return (NULL); - event_assign(ev, base, fd, events, cb, arg); + if (event_assign(ev, base, fd, events, cb, arg) < 0) { + mm_free(ev); + return (NULL); + } return (ev); } diff --git a/include/event2/event.h b/include/event2/event.h index 27ca6ba8..5358e9d3 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -422,10 +422,12 @@ int event_base_got_break(struct event_base *); @param fn callback function to be invoked when the event occurs @param arg an argument to be passed to the callback function + @return 0 if success, or -1 on invalid arguments. + @see event_add(), event_del(), event_once() */ -void event_assign(struct event *, struct event_base *, evutil_socket_t, short, void (*)(evutil_socket_t, short, void *), void *); +int event_assign(struct event *, struct event_base *, evutil_socket_t, short, void (*)(evutil_socket_t, short, void *), void *); /** Create and allocate a new event structure, ready to be added. diff --git a/test/regress.c b/test/regress.c index dce50d6f..eef9859b 100644 --- a/test/regress.c +++ b/test/regress.c @@ -986,6 +986,19 @@ end: event_del(&ev1); } +static void +test_bad_assign(void *ptr) +{ + struct event ev; + int r; + /* READ|SIGNAL is not allowed */ + r = event_assign(&ev, NULL, -1, EV_SIGNAL|EV_READ, dummy_read_cb, NULL); + tt_int_op(r,==,-1); + +end: + ; +} + static void test_event_base_new(void *ptr) { @@ -1784,6 +1797,8 @@ struct testcase_t main_testcases[] = { BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE), + BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), + /* These are still using the old API */ LEGACY(persistent_timeout, TT_FORK|TT_NEED_BASE), LEGACY(priorities, TT_FORK|TT_NEED_BASE),