]> granicus.if.org Git - libevent/commitdiff
Give event_assign a return value, and make it less inclined to exit().
authorNick Mathewson <nickm@torproject.org>
Tue, 27 Oct 2009 04:25:45 +0000 (04:25 +0000)
committerNick Mathewson <nickm@torproject.org>
Tue, 27 Oct 2009 04:25:45 +0000 (04:25 +0000)
We also refactor event_assign so that it is the core function, and
event_set() is only the wrapper.

svn:r1469

ChangeLog
event.c
include/event2/event.h
test/regress.c

index 878ac8fe5d3b1c1588d57329fdc144a2246306c5..cef1fda75e8ee1e4e399258ed4c492e80a97df2d 100644 (file)
--- 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 c484c758238b65f404d22256cdad982acfdab59a..d82c7c6e093f0a484c883eadf6cb8be0ab95954a 100644 (file)
--- 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);
 }
index 27ca6ba881ae906db0d976301f6eca0a8904e5ae..5358e9d311ecc18821269140e099769253152af9 100644 (file)
@@ -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.
index dce50d6f397da99762ed4bc462c257fb247a47de..eef9859bc1b813031005dcf53403fa704bd05513 100644 (file)
@@ -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),