diff --git a/event.c b/event.c index 8935ad69..e1b76adf 100644 --- a/event.c +++ b/event.c @@ -125,6 +125,8 @@ struct event_base *event_global_current_base_ = NULL; static int use_monotonic; +static void *event_self_cbarg_ptr_ = NULL; + /* Prototypes */ static inline int event_add_internal(struct event *ev, const struct timeval *tv, int tv_is_absolute); @@ -1844,6 +1846,8 @@ event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, shor { if (!base) base = current_base; + if (arg == &event_self_cbarg_ptr_) + arg = ev; event_debug_assert_not_added_(ev); @@ -1910,6 +1914,12 @@ event_set(struct event *ev, evutil_socket_t fd, short events, EVUTIL_ASSERT(r == 0); } +void * +event_self_cbarg(void) +{ + return &event_self_cbarg_ptr_; +} + struct event * event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg) { @@ -1917,6 +1927,8 @@ 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); + if (arg == &event_self_cbarg_ptr_) + arg = ev; if (event_assign(ev, base, fd, events, cb, arg) < 0) { mm_free(ev); return (NULL); diff --git a/include/event2/event.h b/include/event2/event.h index 54871eeb..41df727f 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -845,6 +845,30 @@ int event_base_got_break(struct event_base *); */ typedef void (*event_callback_fn)(evutil_socket_t, short, void *); +/** + Return a value used to specify that the event itself must be used as the callback argument. + + The function event_new() takes a callback argument which is passed + to the event's callback function. To specify that the argument to be + passed to the callback function is the event that event_new() returns, + pass in the return value of event_self_cbarg() as the callback argument + for event_new(). + + For example: +
+      struct event *ev = event_new(base, sock, events, callback, %event_self_cbarg());
+  
+ + For consistency with event_new(), it is possible to pass the return value + of this function as the callback argument for event_assign() – this + achieves the same result as passing the event in directly. + + @return a value to be passed as the callback argument to event_new() or + event_assign(). + @see event_new(), event_assign() + */ +void *event_self_cbarg(void); + /** Allocate and asssign a new event structure, ready to be added. diff --git a/sample/signal-test.c b/sample/signal-test.c index 50cc4301..5d432bf0 100644 --- a/sample/signal-test.c +++ b/sample/signal-test.c @@ -24,7 +24,7 @@ #include #include -#include +#include #ifdef EVENT____func__ #define __func__ EVENT____func__ @@ -37,7 +37,7 @@ signal_cb(evutil_socket_t fd, short event, void *arg) { struct event *signal = arg; - printf("%s: got signal %d\n", __func__, EVENT_SIGNAL(signal)); + printf("%s: got signal %d\n", __func__, event_get_signal(signal)); if (called >= 2) event_del(signal); @@ -48,7 +48,7 @@ signal_cb(evutil_socket_t fd, short event, void *arg) int main(int argc, char **argv) { - struct event signal_int; + struct event *signal_int; struct event_base* base; #ifdef _WIN32 WORD wVersionRequested; @@ -64,10 +64,9 @@ main(int argc, char **argv) base = event_base_new(); /* Initalize one event */ - event_assign(&signal_int, base, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb, - &signal_int); + signal_int = evsignal_new(base, SIGINT, signal_cb, event_self_cbarg()); - event_add(&signal_int, NULL); + event_add(signal_int, NULL); event_base_dispatch(base); event_base_free(base); diff --git a/test/regress.c b/test/regress.c index 024f2be8..9f9ad50e 100644 --- a/test/regress.c +++ b/test/regress.c @@ -1227,6 +1227,42 @@ end: event_del(&ev1); } +static void +event_selfarg_cb(evutil_socket_t fd, short event, void *arg) +{ + struct event *ev = arg; + struct event_base *base = event_get_base(ev); + event_base_assert_ok_(base); + event_base_loopexit(base, NULL); +} + +static void +test_event_new_selfarg(void *ptr) +{ + struct basic_test_data *data = ptr; + struct event_base *base = data->base; + struct event *ev = event_new(base, -1, EV_READ, event_selfarg_cb, + event_self_cbarg()); + + event_active(ev, EV_READ, 1); + event_base_dispatch(base); + + event_free(ev); +} + +static void +test_event_assign_selfarg(void *ptr) +{ + struct basic_test_data *data = ptr; + struct event_base *base = data->base; + struct event ev; + + event_assign(&ev, base, -1, EV_READ, event_selfarg_cb, + event_self_cbarg()); + event_active(&ev, EV_READ, 1); + event_base_dispatch(base); +} + static void test_bad_assign(void *ptr) { @@ -2335,6 +2371,8 @@ struct testcase_t main_testcases[] = { BASIC(free_active_base, TT_FORK|TT_NEED_SOCKETPAIR), BASIC(manipulate_active_events, TT_FORK|TT_NEED_BASE), + BASIC(event_new_selfarg, TT_FORK|TT_NEED_BASE), + BASIC(event_assign_selfarg, TT_FORK|TT_NEED_BASE), BASIC(bad_assign, TT_FORK|TT_NEED_BASE|TT_NO_LOGS), BASIC(bad_reentrant, TT_FORK|TT_NEED_BASE|TT_NO_LOGS),