/* Timer pops every 1 ms, writing a new value to key. * After 10 calls, it calls kvs_unwatch(). * After 20 calls, it calls flux_reactor_stop(). * The kvs_unwatch_cb() counts the number of times it is called, should be 10. */ void test_unwatch (int argc, char **argv) { struct timer_ctx ctx; flux_reactor_t *r; int count = 0; flux_watcher_t *timer; if (argc != 1) { fprintf (stderr, "Usage: unwatch key\n"); exit (1); } ctx.key = argv[0]; if (!(ctx.h = flux_open (NULL, 0))) log_err_exit ("flux_open"); r = flux_get_reactor (ctx.h); if (kvs_watch_int (ctx.h, ctx.key, unwatch_watch_cb, &count) < 0) log_err_exit ("kvs_watch_int %s", ctx.key); if (!(timer = flux_timer_watcher_create (r, 0.001, 0.001, unwatch_timer_cb, &ctx))) log_err_exit ("flux_timer_watcher_create"); flux_watcher_start (timer); if (flux_reactor_run (r, 0) < 0) log_err_exit ("flux_reactor_run"); if (count != 10) log_msg_exit ("watch called %d times (should be 10)", count); flux_watcher_destroy (timer); flux_close (ctx.h); }
struct alloc_ctx *alloc_ctx_create (flux_t *h, struct queue *queue, struct event_ctx *event_ctx) { struct alloc_ctx *ctx; flux_reactor_t *r = flux_get_reactor (h); if (!(ctx = calloc (1, sizeof (*ctx)))) return NULL; ctx->h = h; ctx->queue = queue; ctx->event_ctx = event_ctx; if (!(ctx->inqueue = queue_create (false))) goto error; if (flux_msg_handler_addvec (h, htab, ctx, &ctx->handlers) < 0) goto error; ctx->prep = flux_prepare_watcher_create (r, prep_cb, ctx); ctx->check = flux_check_watcher_create (r, check_cb, ctx); ctx->idle = flux_idle_watcher_create (r, NULL, NULL); if (!ctx->prep || !ctx->check || !ctx->idle) { errno = ENOMEM; goto error; } flux_watcher_start (ctx->prep); flux_watcher_start (ctx->check); event_ctx_set_alloc_ctx (event_ctx, ctx); return ctx; error: alloc_ctx_destroy (ctx); return NULL; }
void test_selfmod (int argc, char **argv) { flux_t *h; char *key; if (argc != 1) { fprintf (stderr, "Usage: selfmod key\n"); exit (1); } key = argv[0]; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (kvs_put_int (h, key, -1) < 0) log_err_exit ("kvs_put_int"); if (kvs_commit (h) < 0) log_err_exit ("kvs_commit"); if (kvs_watch_int (h, key, selfmod_watch_cb, h) < 0) log_err_exit ("kvs_watch_int"); log_msg ("reactor: start"); flux_reactor_run (flux_get_reactor (h), 0); log_msg ("reactor: end"); flux_close (h); }
/* check: * Runs right after reactor calls poll(2). * Stop idle watcher, and send next alloc request, if available. */ static void check_cb (flux_reactor_t *r, flux_watcher_t *w, int revents, void *arg) { struct alloc_ctx *ctx = arg; struct job *job; flux_watcher_stop (ctx->idle); if (!ctx->ready) return; if (ctx->mode == SCHED_SINGLE && ctx->active_alloc_count > 0) return; if ((job = queue_first (ctx->inqueue))) { if (alloc_request (ctx, job) < 0) { flux_log_error (ctx->h, "alloc_request fatal error"); flux_reactor_stop_error (flux_get_reactor (ctx->h)); return; } queue_delete (ctx->inqueue, job, job->aux_queue_handle); job->aux_queue_handle = NULL; job->alloc_pending = 1; job->alloc_queued = 0; ctx->active_alloc_count++; if ((job->flags & FLUX_JOB_DEBUG)) (void)event_job_post_pack (ctx->event_ctx, job, "debug.alloc-request", NULL); } }
static void test_multmatch (flux_t h) { flux_msg_handler_t *w1, *w2; struct flux_match m1 = FLUX_MATCH_ANY; struct flux_match m2 = FLUX_MATCH_ANY; m1.topic_glob = "foo.*"; m2.topic_glob = "foo.bar"; /* test #1: verify multiple match behaves as documented, that is, * a message is matched (only) by the most recently added watcher */ ok ((w1 = flux_msg_handler_create (h, m1, multmatch1, NULL)) != NULL, "multmatch: first added handler for foo.*"); ok ((w2 = flux_msg_handler_create (h, m2, multmatch2, NULL)) != NULL, "multmatch: next added handler for foo.bar"); flux_msg_handler_start (w1); flux_msg_handler_start (w2); ok (send_request (h, "foo.bar") == 0, "multmatch: send foo.bar msg"); ok (send_request (h, "foo.baz") == 0, "multmatch: send foo.baz msg"); ok (flux_reactor_run (flux_get_reactor (h), 0) == 0 && multmatch_count == 2, "multmatch: last added watcher handled foo.bar"); flux_msg_handler_destroy (w1); flux_msg_handler_destroy (w2); }
int mod_main (flux_t *h, int argc, char **argv) { ctx_t *ctx = getctx (h); uint32_t rank; flux_msg_handler_t **handlers = NULL; int rc = -1; if (flux_get_rank (h, &rank) < 0) return -1; if (rank != 0) { flux_log (h, LOG_ERR, "this module must only run on rank 0"); return -1; } flux_log (h, LOG_INFO, "module starting"); if (flux_event_subscribe (h, "sim.start") < 0) { flux_log (h, LOG_ERR, "subscribing to event: %s", strerror (errno)); return -1; } if (flux_msg_handler_addvec (h, htab, ctx, &handlers) < 0) { flux_log (h, LOG_ERR, "flux_msg_handler_add: %s", strerror (errno)); return -1; } send_alive_request (h, module_name); if (flux_reactor_run (flux_get_reactor (h), 0) < 0) { flux_log (h, LOG_ERR, "flux_reactor_run: %s", strerror (errno)); goto done_delvec; } rc = 0; done_delvec: flux_msg_handler_delvec (handlers); return rc; }
int mod_main (flux_t *h, int argc, char **argv) { flux_msg_handler_t **handlers = NULL; sqlite_ctx_t *ctx = getctx (h); if (!ctx) goto done; if (flux_event_subscribe (h, "shutdown") < 0) { flux_log_error (h, "flux_event_subscribe"); goto done; } if (flux_msg_handler_addvec (h, htab, ctx, &handlers) < 0) { flux_log_error (h, "flux_msg_handler_addvec"); goto done; } if (register_backing_store (h, true, "content-sqlite") < 0) { flux_log_error (h, "registering backing store"); goto done; } if (register_content_backing_service (h) < 0) { flux_log_error (h, "service.add: content-backing"); goto done; } if (flux_reactor_run (flux_get_reactor (h), 0) < 0) { flux_log_error (h, "flux_reactor_run"); goto done; } done: flux_msg_handler_delvec (handlers); return 0; }
int mod_main (flux_t *h, int argc, char **argv) { int saved_errno; flux_msg_handler_t **handlers = NULL; if (argc == 1 && !strcmp (argv[0], "--init-failure")) { flux_log (h, LOG_INFO, "aborting during init per test request"); errno = EIO; goto error; } if (!(modules = zhash_new ())) { errno = ENOMEM; goto error; } if (flux_get_rank (h, &rank) < 0) goto error; if (flux_msg_handler_addvec (h, htab, NULL, &handlers) < 0) goto error; if (flux_reactor_run (flux_get_reactor (h), 0) < 0) { flux_log_error (h, "flux_reactor_run"); goto error; } zhash_destroy (&modules); return 0; error: saved_errno = errno; flux_msg_handler_delvec (handlers); zhash_destroy (&modules); errno = saved_errno; return -1; }
int heartbeat_start (heartbeat_t *hb) { uint32_t rank; struct flux_match match = FLUX_MATCH_EVENT; if (!hb->h) { errno = EINVAL; return -1; } if (flux_get_rank (hb->h, &rank) < 0) return -1; if (rank == 0) { flux_reactor_t *r = flux_get_reactor (hb->h); flux_reactor_now_update (r); if (!(hb->timer = flux_timer_watcher_create (r, hb->rate, hb->rate, timer_cb, hb))) return -1; flux_watcher_start (hb->timer); } match.topic_glob = "hb"; if (!(hb->mh = flux_msg_handler_create (hb->h, match, event_cb, hb))) return -1; flux_msg_handler_start (hb->mh); return 0; }
int main (int argc, char **argv) { flux_t h; heartbeat_t *hb; flux_msg_handler_t *w; plan (18); check_codec (); (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 ((hb = heartbeat_create ()) != NULL, "heartbeat_create works"); heartbeat_set_flux (hb, h); ok (heartbeat_get_rate (hb) == 2., "heartbeat_get_rate returns default of 2s"); errno = 0; ok (heartbeat_set_rate (hb, -1) < 1 && errno == EINVAL, "heartbeat_set_rate -1 fails with EINVAL"); errno = 0; ok (heartbeat_set_rate (hb, 1000000) < 1 && errno == EINVAL, "heartbeat_set_rate 1000000 fails with EINVAL"); ok (heartbeat_set_ratestr (hb, "250ms") == 0, "heartbeat_set_ratestr 250ms works"); ok (heartbeat_get_rate (hb) == 0.250, "heartbeat_get_rate returns what was set"); ok (heartbeat_set_rate (hb, 0.1) == 0, "heartbeat_set_rate 0.1 works"); ok (heartbeat_get_rate (hb) == 0.1, "heartbeat_get_rate returns what was set"); ok (heartbeat_get_epoch (hb) == 0, "heartbeat_get_epoch works, default is zero"); w = flux_msg_handler_create (h, FLUX_MATCH_EVENT, heartbeat_event_cb, hb); ok (w != NULL, "created event watcher"); flux_msg_handler_start (w); ok (heartbeat_start (hb) == 0, "heartbeat_start works"); ok (flux_reactor_run (flux_get_reactor (h), 0) == 0, "flux reactor exited normally"); heartbeat_destroy (hb); flux_msg_handler_destroy (w); flux_close (h); done_testing (); return 0; }
static struct dispatch *dispatch_get (flux_t h) { struct dispatch *d = flux_aux_get (h, "flux::dispatch"); if (!d) { flux_reactor_t *r = flux_get_reactor (h); if (!(d = malloc (sizeof (*d)))) goto nomem; memset (d, 0, sizeof (*d)); d->usecount = 1; if (!(d->handlers = zlist_new ())) goto nomem; if (!(d->handlers_new = zlist_new ())) goto nomem; d->h = h; d->w = flux_handle_watcher_create (r, h, FLUX_POLLIN, handle_cb, d); if (!d->w) goto nomem; fastpath_init (&d->norm); fastpath_init (&d->group); flux_aux_set (h, "flux::dispatch", d, dispatch_destroy); } return d; nomem: dispatch_destroy (d); errno = ENOMEM; return NULL; }
int mod_main (flux_t *h, int argc, char **argv) { int rc = -1; ctx_t *ctx = getctx (h); if (!ctx) goto done; if (flux_event_subscribe (h, "barrier.") < 0) { flux_log_error (h, "flux_event_subscribe"); goto done; } if (flux_msg_handler_addvec (h, htab, ctx) < 0) { flux_log_error (h, "flux_msghandler_add"); goto done; } if (flux_reactor_run (flux_get_reactor (h), 0) < 0) { flux_log_error (h, "flux_reactor_run"); goto done_unreg; } rc = 0; done_unreg: flux_msg_handler_delvec (htab); done: return rc; }
static int wait_job_complete (flux_t h) { int rc = -1; sig_flux_h = h; wjctx_t *ctx = getctx (h); if (signal (SIGINT, sig_handler) == SIG_ERR) goto done; if (jsc_notify_status (h, waitjob_cb, (void *)h) != 0) { flux_log (h, LOG_ERR, "failed to register a waitjob CB"); } /* once jsc_notify_status is returned, all of JSC events * will be queued and delivered. It is safe to signal * readiness. */ if (ctx->start) touch_outfile (ctx->start); if (complete_job (ctx)) { if (ctx->complete) touch_outfile (ctx->complete); flux_log (ctx->h, LOG_INFO, "wait_job_complete: completion detected"); } if (flux_reactor_run (flux_get_reactor (h), 0) < 0) { flux_log (h, LOG_ERR, "error in flux_reactor_run"); goto done; } rc = 0; done: return rc; }
void *thread (void *arg) { thd_t *t = arg; if (!(t->h = flux_open (NULL, 0))) { log_err ("%d: flux_open", t->n); goto done; } signal_ready (); /* The first kvs.watch reply is handled synchronously, then other kvs.watch * replies will arrive asynchronously and be handled by the reactor. */ if (kvs_watch_int (t->h, key, mt_watch_cb, t) < 0) { log_err ("%d: kvs_watch_int", t->n); goto done; } if (kvs_watch_int (t->h, "nonexistent-key", mt_watchnil_cb, t) < 0) { log_err ("%d: kvs_watch_int", t->n); goto done; } if (kvs_watch_int (t->h, key_stable, mt_watchstable_cb, t) < 0) { log_err ("%d: kvs_watch_int", t->n); goto done; } if (flux_reactor_run (flux_get_reactor (t->h), 0) < 0) { log_err ("%d: flux_reactor_run", t->n); goto done; } done: if (t->h) flux_close (t->h); return NULL; }
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");
static ctx_t *getctx (flux_t *h) { ctx_t *ctx = (ctx_t *)flux_aux_get (h, "flux::barrier"); if (!ctx) { ctx = xzmalloc (sizeof (*ctx)); if (!(ctx->barriers = zhash_new ())) { errno = ENOMEM; goto error; } if (flux_get_rank (h, &ctx->rank) < 0) { flux_log_error (h, "flux_get_rank"); goto error; } if (!(ctx->timer = flux_timer_watcher_create (flux_get_reactor (h), barrier_reduction_timeout_sec, 0., timeout_cb, ctx) )) { flux_log_error (h, "flux_timer_watacher_create"); goto error; } ctx->h = h; flux_aux_set (h, "flux::barrier", ctx, freectx); } return ctx; error: freectx (ctx); return NULL; }
int mod_main (flux_t h, int argc, char **argv) { int saved_errno; ctx_t *ctx = getctx (h); if (!ctx) { saved_errno = errno; flux_log_error (h, "error allocating context"); goto error; } if (flux_msg_handler_addvec (h, htab, ctx) < 0) { saved_errno = errno; flux_log_error (h, "flux_msg_handler_addvec"); goto error; } if (flux_reactor_run (flux_get_reactor (h), 0) < 0) { saved_errno = errno; flux_log_error (h, "flux_reactor_run"); flux_msg_handler_delvec (htab); goto error; } flux_msg_handler_delvec (htab); return 0; error: errno = saved_errno; return -1; }
/* Handle the simplest possible request. * Verify that everything is as expected; log it and stop the reactor if not. */ void null_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = arg; const char *topic; int type, size; void *buf; uint32_t nodeid; int flags; if (!msg) { flux_log (h, LOG_ERR, "%s: got NULL msg!", __FUNCTION__); goto error; } if (flux_msg_get_type (msg, &type) < 0) { flux_log_error (h, "%s: flux_msg_get_type", __FUNCTION__); goto error; } if (type != FLUX_MSGTYPE_REQUEST) { flux_log (h, LOG_ERR, "%s: unexpected type %s", __FUNCTION__, flux_msg_typestr (type)); goto error; } if (flux_msg_get_nodeid (msg, &nodeid, &flags) < 0) { flux_log_error (h, "%s: flux_msg_get_nodeid", __FUNCTION__); goto error; } if (nodeid != ctx->rank && nodeid != FLUX_NODEID_ANY) { flux_log (h, LOG_ERR, "%s: unexpected nodeid: %"PRIu32"", __FUNCTION__, nodeid); goto error; } if (flux_msg_get_topic (msg, &topic) < 0) { flux_log_error (h, "%s: flux_msg_get_topic", __FUNCTION__); goto error; } if (strcmp (topic, "req.null") != 0) { flux_log (h, LOG_ERR, "%s: unexpected topic: %s", __FUNCTION__, topic); goto error; } if (flux_msg_get_payload (msg, &flags, &buf, &size) == 0) { flux_log (h, LOG_ERR, "%s: unexpected payload size %d", __FUNCTION__, size); goto error; } if (errno != EPROTO) { flux_log (h, LOG_ERR, "%s: get nonexistent payload: %s", __FUNCTION__, strerror (errno)); goto error; } if (flux_respond (h, msg, 0, NULL) < 0) { flux_log_error (h, "%s: flux_respond", __FUNCTION__); goto error; } return; error: flux_reactor_stop_error (flux_get_reactor (h)); }
static void multmatch2 (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *topic; if (flux_msg_get_topic (msg, &topic) < 0 || strcmp (topic, "foo.bar")) flux_reactor_stop_error (flux_get_reactor (h)); flux_msg_handler_stop (w); multmatch_count++; }
static void then_cb (flux_rpc_t *r, void *arg) { flux_t h = arg; uint32_t nodeid; if (flux_rpc_get (r, &nodeid, NULL) < 0 || !nodeset_add_rank (then_ns, nodeid) || ++then_count == 128) { flux_reactor_stop (flux_get_reactor (h)); } }
void *watchthread (void *arg) { thd_t *t = arg; watch_count_t wc; flux_kvs_txn_t *txn; flux_future_t *f; flux_reactor_t *r; flux_watcher_t *pw = NULL; flux_watcher_t *tw = NULL; if (!(t->h = flux_open (NULL, 0))) log_err_exit ("flux_open"); /* Make sure key doesn't already exist, initial value may affect * test by chance (i.e. initial value = 0, commit 0 and thus no * change) */ if (!(txn = flux_kvs_txn_create ())) log_err_exit ("flux_kvs_txn_create"); if (flux_kvs_txn_unlink (txn, 0, key) < 0) log_err_exit ("flux_kvs_txn_unlink"); if (!(f = flux_kvs_commit (t->h, 0, txn)) || flux_future_get (f, NULL) < 0) log_err_exit ("flux_kvs_commit"); flux_future_destroy (f); flux_kvs_txn_destroy (txn); r = flux_get_reactor (t->h); if (flux_kvs_watch (t->h, key, watch_count_cb, t) < 0) log_err_exit ("flux_kvs_watch %s", key); pw = flux_prepare_watcher_create (r, watch_prepare_cb, NULL); wc.t = t; wc.lastcount = -1; /* So test won't hang if there's a bug */ tw = flux_timer_watcher_create (r, WATCH_TIMEOUT, WATCH_TIMEOUT, watch_timeout_cb, &wc); flux_watcher_start (pw); flux_watcher_start (tw); if (flux_reactor_run (r, 0) < 0) log_err_exit ("flux_reactor_run"); flux_watcher_destroy (pw); flux_watcher_destroy (tw); flux_close (t->h); return NULL; }
static void then_cb (flux_rpc_t *r, void *arg) { flux_t *h = arg; const char *json_str; ok (flux_rpc_check (r) == true, "flux_rpc_check says get won't block in then callback"); json_str = NULL; ok (flux_rpc_get (r, &json_str) == 0 && json_str && !strcmp (json_str, "{}"), "flux_rpc_get works and returned expected payload in then callback"); flux_reactor_stop (flux_get_reactor (h)); }
int mod_main (flux_t *h, int argc, char **argv) { zhash_t *args = zhash_fromargv (argc, argv); ctx_t *ctx; char *eoc_str; bool exit_on_complete; uint32_t rank; if (flux_get_rank (h, &rank) < 0) return -1; if (rank != 0) { flux_log (h, LOG_ERR, "sim module must only run on rank 0"); return -1; } flux_log (h, LOG_INFO, "sim comms module starting"); if (!(eoc_str = zhash_lookup (args, "exit-on-complete"))) { flux_log (h, LOG_ERR, "exit-on-complete argument is not set, defaulting to false"); exit_on_complete = false; } else { exit_on_complete = (!strcmp (eoc_str, "true") || !strcmp (eoc_str, "True")); } ctx = getctx (h, exit_on_complete); if (flux_event_subscribe (h, "rdl.update") < 0) { flux_log (h, LOG_ERR, "subscribing to event: %s", strerror (errno)); return -1; } if (flux_msg_handler_addvec (h, htab, ctx) < 0) { flux_log (h, LOG_ERR, "flux_msg_handler_add: %s", strerror (errno)); return -1; } if (send_start_event (h) < 0) { flux_log (h, LOG_ERR, "sim failed to send start event"); return -1; } flux_log (h, LOG_DEBUG, "sim sent start event"); if (flux_reactor_run (flux_get_reactor (h), 0) < 0) { flux_log (h, LOG_ERR, "flux_reactor_run: %s", strerror (errno)); return -1; } return 0; }
int main (int argc, char *argv[]) { flux_msg_t *msg; flux_t h; flux_reactor_t *reactor; plan (35); (void)setenv ("FLUX_CONNECTOR_PATH", CONNECTOR_PATH, 0); ok ((h = flux_open ("loop://", FLUX_O_COPROC)) != NULL, "opened loop connector"); if (!h) BAIL_OUT ("can't continue without loop handle"); ok ((reactor = flux_get_reactor (h)) != NULL, "obtained reactor"); if (!reactor) BAIL_OUT ("can't continue without reactor"); flux_fatal_set (h, fatal_err, NULL); flux_fatal_error (h, __FUNCTION__, "Foo"); ok (fatal_tested == true, "flux_fatal function is called on fatal error"); /* create nodeset for last _then test */ ok ((then_ns = nodeset_create ()) != NULL, "nodeset created ok"); ok (flux_msghandler_addvec (h, htab, htablen, NULL) == 0, "registered message handlers"); /* test continues in rpctest_begin_cb() so that rpc calls * can sleep while we answer them */ ok ((msg = flux_request_encode ("rpctest.begin", NULL)) != NULL && flux_send (h, msg, 0) == 0, "sent message to initiate test"); ok (flux_reactor_run (reactor, 0) == 0, "reactor completed normally"); flux_msg_destroy (msg); /* Check result of last _then test */ ok (nodeset_count (then_ns) == 128, "then callback worked with correct nodemap"); nodeset_destroy (then_ns); flux_rpc_destroy (then_r); flux_close (h); done_testing(); return (0); }
static int runlevel_start_subprocess (runlevel_t *r, int level) { flux_subprocess_t *p = NULL; assert (r->h != NULL); if (r->rc[level].cmd) { flux_subprocess_ops_t ops = { .on_completion = completion_cb, .on_state_change = NULL, .on_channel_out = NULL, .on_stdout = NULL, .on_stderr = NULL, }; flux_reactor_t *reactor = flux_get_reactor (r->h); int flags = 0; /* set alternate io callback for levels 1 and 3 */ if (level == 1 || level == 3) { ops.on_stdout = io_cb; ops.on_stderr = io_cb; } else flags |= FLUX_SUBPROCESS_FLAGS_STDIO_FALLTHROUGH; if (!(p = flux_exec (r->h, flags, r->rc[level].cmd, &ops))) goto error; if (flux_subprocess_aux_set (p, "runlevel", r, NULL) < 0) goto error; monotime (&r->rc[level].start); if (r->rc[level].timeout > 0.) { flux_watcher_t *w; if (!(w = flux_timer_watcher_create (reactor, r->rc[level].timeout, 0., runlevel_timeout, r))) goto error; flux_watcher_start (w); r->rc[level].timer = w; flux_log (r->h, LOG_INFO, "runlevel %d (%.1fs) timer started", level, r->rc[level].timeout); } r->rc[level].p = p; } else {
static int unwatch_timer_cb (flux_t h, void *arg) { static int count = 0; const char *key = arg; if (kvs_put_int (h, key, count++) < 0) err_exit ("%s: kvs_put_int", __FUNCTION__); if (kvs_commit (h) < 0) err_exit ("%s: kvs_commit", __FUNCTION__); if (count == 10) { if (kvs_unwatch (h, key) < 0) err_exit ("%s: kvs_unwatch", __FUNCTION__); } else if (count == 20) flux_reactor_stop (flux_get_reactor (h)); return 0; }
static void event_handler (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { cron_entry_t *e = arg; struct cron_event *ev = cron_entry_type_data (e); ev->counter++; if (ev->paused) return; /* * Determine if we should run the cron task on this event * based on the current values for "after" and "nth". * If ev->after is set, then only run for the first time * after we've seen this many events. If ev->nth is set, * only run every nth event starting with 'after'. */ if (ev->counter < ev->after) return; if (ev->nth && ((ev->counter - ev->after) % ev->nth)) return; if (ev->min_interval > 0.) { double now = get_timestamp (); double remaining = ev->min_interval - (now - e->stats.lastrun); if (remaining > 1e-5) { flux_reactor_t *r = flux_get_reactor (h); flux_watcher_t *w; if (!(w = flux_timer_watcher_create (r, remaining, 0., ev_timer_cb, (void *) e))) flux_log_error (h, "timer_watcher_create"); else { /* Pause the event watcher. Continue to count events but * don't run anything until we unpause. */ ev->paused = 1; flux_watcher_start (w); flux_log (h, LOG_DEBUG, "cron-%ju: delaying %4.03fs due to min interval", e->id, remaining); } return; } } cron_entry_schedule_task (e); }
static struct dispatch *dispatch_get (flux_t h) { struct dispatch *d = flux_aux_get (h, "flux::dispatch"); if (!d) { flux_reactor_t *r = flux_get_reactor (h); d = xzmalloc (sizeof (*d)); d->handlers = zlist_new (); d->waiters = zlist_new (); if (!d->handlers || !d->waiters) oom (); d->h = h; d->w = flux_handle_watcher_create (r, h, FLUX_POLLIN, handle_cb, d); if (!d->w) oom (); d->usecount = 1; flux_aux_set (h, "flux::dispatch", d, dispatch_destroy); } return d; }
/* expect val: {-1,0,1,...,(changes - 1)} * count will therefore run 0...changes. */ static int mt_watch_cb (const char *k, int val, void *arg, int errnum) { thd_t *t = arg; if (errnum != 0) { log_errn (errnum, "%d: %s", t->n, __FUNCTION__); return -1; } if (val == t->last_val) { log_msg ("%d: %s: called with same value as last time: %d", t->n, __FUNCTION__, val); return -1; } t->last_val = val; /* normal stop */ if (val + 1 == changes) flux_reactor_stop (flux_get_reactor (t->h)); t->change_count++; return 0; }
static int handle_notify_req (flux_t h, const char *ofn) { jstatctx_t *ctx = NULL; sig_flux_h = h; if (signal (SIGINT, sig_handler) == SIG_ERR) return -1; ctx = getctx (h); ctx->op = (ofn)? open_test_outfile (ofn) : stdout; if (jsc_notify_status (h, job_status_cb, (void *)h) != 0) { flux_log (h, LOG_ERR, "failed to reg a job status change CB"); return -1; } if (flux_reactor_run (flux_get_reactor (h), 0) < 0) flux_log (h, LOG_ERR, "error in flux_reactor_run"); return 0; }