diff --git a/src/event/signal.c b/src/event/signal.c index 508146a9a8..d70d80146c 100644 --- a/src/event/signal.c +++ b/src/event/signal.c @@ -56,25 +56,61 @@ #include "event.h" #include "evsignal.h" +#include "util/output.h" extern struct ompi_event_list ompi_signalqueue; static short ompi_evsigcaught[NSIG]; static int ompi_needrecalc; +static int ompi_event_signal_pipe[2]; +static ompi_event_t ompi_event_signal_pipe_event; +static int ompi_event_signal_count = 0; +static bool initialized = false; volatile sig_atomic_t ompi_evsignal_caught = 0; +static void ompi_event_signal_pipe_handler(int sd, short flags, void* user) +{ + unsigned char byte; + if(read(sd, &byte, 1) != 1) { + ompi_output(0, "ompi_event_signal_pipe: read failed with: errno=%d\n", errno); + ompi_event_del(&ompi_event_signal_pipe_event); + } + ompi_event_signal_count = 0; +} + void ompi_evsignal_handler(int sig); void ompi_evsignal_init(sigset_t *evsigmask) { - sigemptyset(evsigmask); + if (pipe(ompi_event_signal_pipe) != 0) { + ompi_output(0, "ompi_evsignal_init: pipe() failed with errno=%d\n", + errno); + return; + } + ompi_event_signal_count = 0; + + sigemptyset(evsigmask); } + int ompi_evsignal_add(sigset_t *evsigmask, struct ompi_event *ev) { int evsignal; + + if (!initialized) { + /* Must delay the event add until after init() because + it may trigger poll events that are not yet setup + to be triggered. */ + ompi_event_set(&ompi_event_signal_pipe_event, + ompi_event_signal_pipe[0], + OMPI_EV_READ|OMPI_EV_PERSIST, + ompi_event_signal_pipe_handler, + 0); + ompi_event_add_i(&ompi_event_signal_pipe_event, 0); + initialized = true; + } if (ev->ev_events & (OMPI_EV_READ|OMPI_EV_WRITE)) errx(1, "%s: OMPI_EV_SIGNAL incompatible use", __func__); @@ -103,8 +139,17 @@ ompi_evsignal_del(sigset_t *evsigmask, struct ompi_event *ev) void ompi_evsignal_handler(int sig) { + const char errmsg[] = "ompi_evsignal_handler: error in write\n"; + ompi_evsigcaught[sig]++; ompi_evsignal_caught = 1; + if (ompi_event_signal_count == 0) { + unsigned char byte = 0; + if (write(ompi_event_signal_pipe[1], &byte, 1) != 1) { + write(2, errmsg, sizeof(errmsg)); + } + ompi_event_signal_count++; + } } int