From ed36e6abea71afcbe691aeeb529bcc668e88bc7d Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 12 Mar 2012 20:42:39 +0200 Subject: [PATCH 1/5] Add event_self_cbarg() to be used in conjunction with event_new(). event_self_cbarg() returns a magic value which makes event_new() pass the event itself as the callback argument. --- event.c | 10 ++++++++++ include/event2/event.h | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/event.c b/event.c index 8935ad69..b98ba953 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); @@ -1910,6 +1912,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 +1925,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..9b584836 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -845,6 +845,25 @@ 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());
+  
+ + @return a value to be passed as the callback argument to event_new(). + @see event_new() + */ +void *event_self_cbarg(void); + /** Allocate and asssign a new event structure, ready to be added. From 817f374dc151845ad076d881aee42bbfadf8e36a Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 12 Mar 2012 20:54:32 +0200 Subject: [PATCH 2/5] Update sample/signal-test.c to use the new event_self_cbarg(). --- sample/signal-test.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) 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); From fa931bb3489bce61620179f60c81e8f9a9d707ab Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Mon, 12 Mar 2012 21:32:45 +0200 Subject: [PATCH 3/5] Add a regression test for event_self_cbarg(). --- test/regress.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/regress.c b/test/regress.c index 024f2be8..d0338db4 100644 --- a/test/regress.c +++ b/test/regress.c @@ -1227,6 +1227,29 @@ 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_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_bad_assign(void *ptr) { @@ -2335,6 +2358,7 @@ 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_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), From 09a1906a2cd36e2776db681bf9796f58d3c0142f Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Tue, 13 Mar 2012 21:41:22 +0200 Subject: [PATCH 4/5] event_self_cbarg() works with event_assign() for consistency with event_new(). --- event.c | 2 ++ include/event2/event.h | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/event.c b/event.c index b98ba953..e1b76adf 100644 --- a/event.c +++ b/event.c @@ -1846,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); diff --git a/include/event2/event.h b/include/event2/event.h index 9b584836..41df727f 100644 --- a/include/event2/event.h +++ b/include/event2/event.h @@ -859,8 +859,13 @@ typedef void (*event_callback_fn)(evutil_socket_t, short, void *); struct event *ev = event_new(base, sock, events, callback, %event_self_cbarg()); - @return a value to be passed as the callback argument to event_new(). - @see event_new() + 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); From 1338e6cd565c700d2b6e7318ea0a83bdd3ce7dc0 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Tue, 13 Mar 2012 21:42:40 +0200 Subject: [PATCH 5/5] Add a test for using event_self_cbarg() with event_assign(). --- test/regress.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/test/regress.c b/test/regress.c index d0338db4..9f9ad50e 100644 --- a/test/regress.c +++ b/test/regress.c @@ -1237,7 +1237,7 @@ event_selfarg_cb(evutil_socket_t fd, short event, void *arg) } static void -test_event_selfarg(void *ptr) +test_event_new_selfarg(void *ptr) { struct basic_test_data *data = ptr; struct event_base *base = data->base; @@ -1250,6 +1250,19 @@ test_event_selfarg(void *ptr) 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) { @@ -2358,7 +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_selfarg, 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),