diff --git a/opal/mca/event/libevent207/libevent207.h b/opal/mca/event/libevent207/libevent207.h index 5068ba4abc..c5bce18d1e 100644 --- a/opal/mca/event/libevent207/libevent207.h +++ b/opal/mca/event/libevent207/libevent207.h @@ -58,7 +58,19 @@ #include "opal/mca/event/event.h" typedef struct event opal_event_t; -typedef struct event_base opal_event_base_t; +/*** Overload the event_base_t struct ***/ +/* This may (hopefully) be a temporary change + * to deal with cross-base sync. Specifically, + * when an event in one base needs to release + * a condition_wait in another base, we need + * to "wakeup" the event base in the second base + * so the condition_wait can be checked + */ +typedef struct { + struct event_base *base; + opal_event_t wakeup_event; + int wakeup_pipe[2]; +} opal_event_base_t; BEGIN_C_DECLS @@ -75,8 +87,9 @@ OPAL_DECLSPEC extern opal_event_base_t *opal_event_base; #define OPAL_EVLOOP_ONCE EVLOOP_ONCE /**< Block at most once. */ #define OPAL_EVLOOP_NONBLOCK EVLOOP_NONBLOCK /**< Do not block. */ -/* Global function to create an event base */ +/* Global function to create and release an event base */ OPAL_DECLSPEC opal_event_base_t* opal_event_base_create(void); +OPAL_DECLSPEC void opal_event_base_finalize(opal_event_base_t *base); OPAL_DECLSPEC int opal_event_init(void); @@ -92,11 +105,9 @@ OPAL_DECLSPEC int opal_event_init(void); #endif /* Basic event APIs */ -#define opal_event_base_finalize(x) event_base_free((x)) - #define opal_event_set_debug_output(x) event_set_debug_output((x)) -#define opal_event_set(b, ev, fd, fg, cb, arg) event_assign((ev), (b), (fd), (fg), (event_callback_fn) (cb), (arg)) +#define opal_event_set(b, ev, fd, fg, cb, arg) event_assign((ev), (b)->base, (fd), (fg), (event_callback_fn) (cb), (arg)) #define opal_event_add(ev, tv) event_add((ev), (tv)) @@ -105,11 +116,11 @@ OPAL_DECLSPEC int opal_event_init(void); #define opal_event_active(x, y, z) event_active((x), (y), (z)) /* Timer APIs */ -#define opal_event_evtimer_new(b, cb, arg) event_new((b), -1, 0, (event_callback_fn) (cb), (arg)) +#define opal_event_evtimer_new(b, cb, arg) event_new((b)->base, -1, 0, (event_callback_fn) (cb), (arg)) #define opal_event_evtimer_add(ev, tv) event_add((ev), (tv)) -#define opal_event_evtimer_set(b, ev, cb, arg) event_assign((ev), (b), -1, 0, (event_callback_fn) (cb), (arg)) +#define opal_event_evtimer_set(b, ev, cb, arg) event_assign((ev), (b)->base, -1, 0, (event_callback_fn) (cb), (arg)) #define opal_event_evtimer_del(ev) event_del((ev)) @@ -120,7 +131,7 @@ OPAL_DECLSPEC int opal_event_init(void); /* Signal APIs */ #define opal_event_signal_add(ev, tv) event_add((ev), (tv)) -#define opal_event_signal_set(b, ev, fd, cb, arg) event_assign((ev), (b), (fd), EV_SIGNAL|EV_PERSIST, (event_callback_fn) (cb), (arg)) +#define opal_event_signal_set(b, ev, fd, cb, arg) event_assign((ev), (b)->base, (fd), EV_SIGNAL|EV_PERSIST, (event_callback_fn) (cb), (arg)) #define opal_event_signal_del(ev) event_del((ev)) @@ -130,9 +141,9 @@ OPAL_DECLSPEC int opal_event_init(void); #define opal_event_get_signal(ev) event_get_signal((ev)) -#define opal_event_loop(b, fg) event_base_loop((b), (fg)) +#define opal_event_loop(b, fg) event_base_loop((b->base), (fg)) -#define opal_event_dispatch(b) event_base_loop((b), 0) +#define opal_event_dispatch(b) event_base_loop((b)->base, 0) END_C_DECLS diff --git a/opal/mca/event/libevent207/libevent207_module.c b/opal/mca/event/libevent207/libevent207_module.c index cc134649d5..8c0782a387 100644 --- a/opal/mca/event/libevent207/libevent207_module.c +++ b/opal/mca/event/libevent207/libevent207_module.c @@ -3,6 +3,7 @@ * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. */ #include "opal_config.h" +#include "opal/constants.h" #include "config.h" #ifdef HAVE_SYS_TYPES_H @@ -36,9 +37,10 @@ #include "opal/threads/mutex.h" #include "opal/threads/threads.h" #include "opal/util/output.h" -#include "opal/constants.h" #include "opal/util/argv.h" +#include "opal/util/fd.h" #include "opal/mca/base/mca_base_param.h" + #include "libevent207.h" #include "opal/mca/event/base/base.h" @@ -98,17 +100,60 @@ static const struct eventop *eventops[] = { static struct event_config *config=NULL; +static void wakeup_event(int fd, short flags, void* arg) +{ + char byte; + + /* clear the event */ + opal_fd_read(fd, 1, &byte); + return; +} + /* Public function -- not part of the module */ +/* This includes (hopefully) a temporary change + * to deal with cross-base sync. Specifically, + * when an event in one base needs to release + * a condition_wait in another base, we need + * to "wakeup" the event base in the second base + * so the condition_wait can be checked + */ opal_event_base_t* opal_event_base_create(void) { struct event_base *base; + opal_event_base_t *evbase; base = event_base_new_with_config(config); if (NULL == base) { /* there is no backend method that does what we want */ opal_output(0, "No event method available"); + return NULL; } - return base; + evbase = (opal_event_base_t*)malloc(sizeof(opal_event_base_t)); + evbase->base = base; + if (pipe(evbase->wakeup_pipe) < 0) { + opal_output(0, "Unable to open wakeup pipe"); + free(evbase); + event_base_free(base); + return NULL; + } + event_assign(&evbase->wakeup_event, base, + evbase->wakeup_pipe[0], EV_READ | EV_PERSIST, + wakeup_event, NULL); + event_add(&evbase->wakeup_event, 0); + return evbase; +} + +void opal_event_base_finalize(opal_event_base_t *evbase) +{ + /* delete the wakeup event */ + event_del(&evbase->wakeup_event); + /* close the pipe */ + close(evbase->wakeup_pipe[0]); + close(evbase->wakeup_pipe[1]); + /* release the base */ + event_base_free(evbase->base); + /* free the storage */ + free(evbase); } int opal_event_init(void)