int main (int argc, char *argv[]) { flux_t h; flux_reactor_t *reactor; plan (4+11+3+4+3+5+2); (void)setenv ("FLUX_CONNECTOR_PATH", CONNECTOR_PATH, 0); ok ((h = flux_open ("loop://", 0)) != NULL, "opened loop connector"); if (!h) BAIL_OUT ("can't continue without loop handle"); flux_fatal_set (h, fatal_err, NULL); ok ((reactor = flux_get_reactor (h)) != NULL, "obtained reactor"); if (!reactor) BAIL_OUT ("can't continue without reactor"); ok (flux_reactor_run (reactor, 0) == 0, "general: reactor ran to completion (no watchers)"); errno = 0; ok (flux_sleep_on (h, FLUX_MATCH_ANY) < 0 && errno == EINVAL, "general: flux_sleep_on outside coproc fails with EINVAL"); test_timer (reactor); // 11 test_fd (reactor); // 3 test_zmq (reactor); // 4 test_msg (h); // 3 test_multmatch (h); // 5 /* Misc */ lives_ok ({ reactor_destroy_early ();}, "destroying reactor then watcher doesn't segfault");
/* If this function is called without the NONBLOCK flag from a reactor * handler running in coprocess context, the call to flux_sleep_on() * will allow the reactor to run until a message matching 'match' arrives. * The flux_sleep_on() call will then resume, and the next call to recv() * will return the matching message. If not running in coprocess context, * flux_sleep_on() will fail with EINVAL. In that case, the do loop * reading messages and comparing them to match criteria may have to read * a few non-matching messages before finding a match. On return, those * non-matching messages have to be requeued in the handle, hence the * defer_*() helper calls. */ flux_msg_t *flux_recv (flux_t h, struct flux_match match, int flags) { zlist_t *l = NULL; flux_msg_t *msg = NULL; int saved_errno; flags |= h->flags; if (!(flags & FLUX_O_NONBLOCK) && (flags & FLUX_O_COPROC) && flux_sleep_on (h, match) < 0) { if (errno != EINVAL) goto fatal; errno = 0; } do { if (!(msg = flux_recv_any (h, flags))) { if (errno != EAGAIN && errno != EWOULDBLOCK) goto fatal; if (defer_requeue (&l, h) < 0) goto fatal; defer_destroy (&l); errno = EWOULDBLOCK; return NULL; } if (!flux_msg_cmp (msg, match)) { if (defer_enqueue (&l, msg) < 0) goto fatal; msg = NULL; } } while (!msg); update_rx_stats (h, msg); if ((flags & FLUX_O_TRACE)) flux_msg_fprint (stderr, msg); if (defer_requeue (&l, h) < 0) goto fatal; defer_destroy (&l); #if HAVE_CALIPER cali_begin_int (h->prof.msg_match_type, match.typemask); cali_begin_int (h->prof.msg_match_tag, match.matchtag); cali_begin_string (h->prof.msg_match_glob, match.topic_glob ? match.topic_glob : "NONE"); char *sender = NULL; flux_msg_get_route_first (msg, &sender); if (sender) cali_begin_string (h->prof.msg_sender, sender); profiling_msg_snapshot (h, msg, flags, "recv"); if (sender) cali_end (h->prof.msg_sender); cali_end (h->prof.msg_match_type); cali_end (h->prof.msg_match_tag); cali_end (h->prof.msg_match_glob); free (sender); #endif return msg; fatal: saved_errno = errno; FLUX_FATAL (h); if (msg) flux_msg_destroy (msg); defer_destroy (&l); errno = saved_errno; return NULL; }