コード例 #1
0
ファイル: reactor.c プロジェクト: surajpkn/flux-core
static void test_zmq (flux_reactor_t *reactor)
{
    zctx_t *zctx;
    void *zs[2];
    flux_watcher_t *r, *w;

    ok ((zctx = zctx_new ()) != NULL,
        "zmq: created zmq context");
    zs[0] = zsocket_new (zctx, ZMQ_PAIR);
    zs[1] = zsocket_new (zctx, ZMQ_PAIR);
    ok (zs[0] && zs[1]
        && zsocket_bind (zs[0], "inproc://test_zmq") == 0
        && zsocket_connect (zs[1], "inproc://test_zmq") == 0,
        "zmq: connected ZMQ_PAIR sockets over inproc");
    r = flux_zmq_watcher_create (reactor, zs[0], FLUX_POLLIN, zmqreader, NULL);
    w = flux_zmq_watcher_create (reactor, zs[1], FLUX_POLLOUT, zmqwriter, NULL);
    ok (r != NULL && w != NULL,
        "zmq: nonblocking reader and writer created");
    flux_watcher_start (r);
    flux_watcher_start (w);
    ok (flux_reactor_run  (reactor, 0) == 0,
        "zmq: reactor ran to completion after %d messages", zmqwriter_msgcount);
    flux_watcher_stop (r);
    flux_watcher_stop (w);
    flux_watcher_destroy (r);
    flux_watcher_destroy (w);

    zsocket_destroy (zctx, zs[0]);
    zsocket_destroy (zctx, zs[1]);
    zctx_destroy (&zctx);
}
コード例 #2
0
ファイル: transactionmerge.c プロジェクト: trws/flux-core
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;
}
コード例 #3
0
ファイル: modservice.c プロジェクト: cigolabs/flux-core
static void freectx (void *arg)
{
    ctx_t *ctx = arg;
    flux_msg_handler_t *w;
    while ((w = zlist_pop (ctx->handlers)))
        flux_msg_handler_destroy (w);
    zlist_destroy (&ctx->handlers);
    flux_watcher_destroy (ctx->w_prepare);
    flux_watcher_destroy (ctx->w_check);
    free (ctx);
}
コード例 #4
0
ファイル: alloc.c プロジェクト: flux-framework/flux-core
void alloc_ctx_destroy (struct alloc_ctx *ctx)
{
    if (ctx) {
        int saved_errno = errno;;
        flux_msg_handler_delvec (ctx->handlers);
        flux_watcher_destroy (ctx->prep);
        flux_watcher_destroy (ctx->check);
        flux_watcher_destroy (ctx->idle);
        queue_destroy (ctx->inqueue);
        free (ctx);
        errno = saved_errno;
    }
}
コード例 #5
0
ファイル: simple.c プロジェクト: dongahn/flux-core
void *server_thread (void *arg)
{
    struct context *ctx = arg;
    flux_reactor_t *reactor = NULL;
    flux_watcher_t *w = NULL;

    if (!(reactor = flux_reactor_create (0)))
        goto done;
    if (!(w = flux_fd_watcher_create (reactor, ctx->fds[1],
                                      FLUX_POLLIN, s_io_cb, ctx)))
        goto done;
    flux_watcher_start (w);

    ctx->exit_rc = -1;
    if (flux_reactor_run (reactor, 0) < 0)
        goto done;

    ctx->exit_rc = 0;
done:
    if (w)
        flux_watcher_destroy (w);
    if (reactor)
        flux_reactor_destroy (reactor);
    return NULL;
}
コード例 #6
0
ファイル: watch.c プロジェクト: SteVwonder/flux-core
/* 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);
}
コード例 #7
0
ファイル: subprocess.c プロジェクト: cigolabs/flux-core
static void subprocess_free (struct subprocess *p)
{
    assert (p != NULL);

    if (p->sm)
        zlist_remove (p->sm->processes, (void *) p);
    zhash_destroy (&p->zhash);
    hooks_table_free (p);

    fda_closeall (p->child_fda);

    if (p->argz)
        free (p->argz);
    if (p->envz)
        free (p->envz);
    if (p->cwd)
        free (p->cwd);

    zio_destroy (p->zio_in);
    zio_destroy (p->zio_out);
    zio_destroy (p->zio_err);

    if (p->parentfd != -1)
        close (p->parentfd);
    if (p->childfd != -1)
        close (p->childfd);
    flux_watcher_destroy (p->child_watcher);

    memset (p, 0, sizeof (*p));
    free (p);
}
コード例 #8
0
ファイル: heartbeat.c プロジェクト: trws/flux-core
void heartbeat_destroy (heartbeat_t *hb)
{
    if (hb) {
        flux_watcher_destroy (hb->timer);
        flux_msg_handler_destroy (hb->mh);
        free (hb);
    }
}
コード例 #9
0
ファイル: shutdown.c プロジェクト: cigolabs/flux-core
void shutdown_disarm (shutdown_t *s)
{
    if (s->timer) {
        flux_watcher_stop (s->timer);
        flux_watcher_destroy (s->timer);
        s->timer = NULL;
    }
}
コード例 #10
0
ファイル: dispatch.c プロジェクト: surajpkn/flux-core
static void dispatch_usecount_decr (struct dispatch *d)
{
    if (d && --d->usecount == 0) {
        flux_watcher_destroy (d->w);
        zlist_destroy (&d->handlers);
        zlist_destroy (&d->waiters);
        free (d);
    }
}
コード例 #11
0
ファイル: reactor.c プロジェクト: surajpkn/flux-core
static void test_timer (flux_reactor_t *reactor)
{
    flux_watcher_t *w;

    errno = 0;
    ok (!flux_timer_watcher_create (reactor, -1, 0, oneshot, NULL)
        && errno == EINVAL,
        "timer: creating negative timeout fails with EINVAL");
    ok (!flux_timer_watcher_create (reactor, 0, -1, oneshot, NULL)
        && errno == EINVAL,
        "timer: creating negative repeat fails with EINVAL");
    ok ((w = flux_timer_watcher_create (reactor, 0, 0, oneshot, NULL)) != NULL,
        "timer: creating zero timeout works");
    flux_watcher_start (w);
    ok (flux_reactor_run (reactor, 0) == 0,
        "timer: reactor ran to completion (single oneshot)");
    ok (oneshot_ran == true,
        "timer: oneshot was executed");
    oneshot_ran = false;
    ok (flux_reactor_run (reactor, 0) == 0,
        "timer: reactor ran to completion (expired oneshot)");
    ok (oneshot_ran == false,
        "timer: expired oneshot was not re-executed");

    errno = 0;
    oneshot_errno = ESRCH;
    flux_watcher_start (w);
    ok (flux_reactor_run (reactor, 0) < 0 && errno == ESRCH,
        "general: reactor stop_error worked with errno passthru");
    flux_watcher_stop (w);
    flux_watcher_destroy (w);

    ok ((w = flux_timer_watcher_create (reactor, 0.01, 0.01, repeat, NULL))
        != NULL,
        "timer: creating 1ms timeout with 1ms repeat works");
    flux_watcher_start (w);
    ok (flux_reactor_run (reactor, 0) == 0,
        "timer: reactor ran to completion (single repeat)");
    ok (repeat_countdown == 0,
        "timer: repeat timer stopped itself after countdown");
    flux_watcher_stop (w);
    flux_watcher_destroy (w);
}
コード例 #12
0
ファイル: hello.c プロジェクト: cigolabs/flux-core
void hello_destroy (hello_t *hello)
{
    if (hello) {
        if (hello->nodeset)
            nodeset_destroy (hello->nodeset);
        if (hello->timer)
            flux_watcher_destroy (hello->timer);
        free (hello);
    }
}
コード例 #13
0
ファイル: barrier.c プロジェクト: SteVwonder/flux-core
static void freectx (void *arg)
{
    ctx_t *ctx = arg;
    if (ctx) {
        zhash_destroy (&ctx->barriers);
        if (ctx->timer)
            flux_watcher_destroy (ctx->timer);
        free (ctx);
    }
}
コード例 #14
0
ファイル: event.c プロジェクト: trws/flux-core
static void ev_timer_cb (flux_reactor_t *r, flux_watcher_t *w,
                         int revents, void *arg)
{
    cron_entry_t *e = arg;
    struct cron_event *ev = cron_entry_type_data (e);
    cron_entry_schedule_task (e);
    flux_watcher_stop (w);
    flux_watcher_destroy (w);
    ev->paused = 0;
}
コード例 #15
0
ファイル: zio.c プロジェクト: trws/flux-core
void zio_destroy (zio_t *z)
{
    if (z == NULL)
        return;
    assert (z->magic == ZIO_MAGIC);
    if (zio_is_in_handler (z)) {
        zio_set_destroyed (z);
        return;
    }
    if (z->buf)
        cbuf_destroy (z->buf);
    free (z->name);
    free (z->prefix);
    zio_close_src_fd (z);
    zio_close_dst_fd (z);
    flux_watcher_destroy (z->reader);
    flux_watcher_destroy (z->writer);
    assert ((z->magic = ~ZIO_MAGIC));
    free (z);
}
コード例 #16
0
ファイル: reactor.c プロジェクト: surajpkn/flux-core
static void reactor_destroy_early (void)
{
    flux_reactor_t *r;
    flux_watcher_t *w;

    if (!(r = flux_reactor_create ()))
        exit (1);
    if (!(w = flux_idle_watcher_create (r, NULL, NULL)))
        exit (1);
    flux_watcher_start (w);
    flux_reactor_destroy (r);
    flux_watcher_destroy (w);
}
コード例 #17
0
ファイル: runlevel.c プロジェクト: flux-framework/flux-core
void runlevel_destroy (runlevel_t *r)
{
    if (r) {
        int i;
        for (i = 0; i < 4; i++) {
            if (r->rc[i].p)
                flux_subprocess_destroy (r->rc[i].p);
            if (r->rc[i].cmd)
                flux_cmd_destroy (r->rc[i].cmd);
            flux_watcher_destroy (r->rc[i].timer);
        }
        free (r);
    }
}
コード例 #18
0
ファイル: reactor.c プロジェクト: surajpkn/flux-core
static void test_fd (flux_reactor_t *reactor)
{
    int fd[2];
    flux_watcher_t *r, *w;

    ok (socketpair (PF_LOCAL, SOCK_STREAM, 0, fd) == 0
        && set_nonblock (fd[0]) == 0 && set_nonblock (fd[1]) == 0,
        "fd: successfully created non-blocking socketpair");
    r = flux_fd_watcher_create (reactor, fd[0], FLUX_POLLIN, fdreader, NULL);
    w = flux_fd_watcher_create (reactor, fd[1], FLUX_POLLOUT, fdwriter, NULL);
    ok (r != NULL && w != NULL,
        "fd: reader and writer created");
    flux_watcher_start (r);
    flux_watcher_start (w);
    ok (flux_reactor_run (reactor, 0) == 0,
        "fd: reactor ran to completion after %lu bytes", fdwriter_bufsize);
    flux_watcher_stop (r);
    flux_watcher_stop (w);
    flux_watcher_destroy (r);
    flux_watcher_destroy (w);
    close (fd[0]);
    close (fd[1]);
}
コード例 #19
0
ファイル: module.c プロジェクト: surajpkn/flux-core
static void module_destroy (module_t *p)
{
    assert (p->magic == MODULE_MAGIC);
    int errnum;

    if (p->t) {
        errnum = pthread_join (p->t, NULL);
        if (errnum)
            errn_exit (errnum, "pthread_join");
    }

    assert (p->h == NULL);

    flux_watcher_stop (p->broker_w);
    flux_watcher_destroy (p->broker_w);
    zsocket_destroy (p->zctx, p->sock);

    dlclose (p->dso);
    zuuid_destroy (&p->uuid);
    free (p->digest);
    if (p->argz)
        free (p->argz);
    if (p->name)
        free (p->name);
    if (p->rmmod_cb)
        p->rmmod_cb (p, p->rmmod_arg);
    if (p->rmmod) {
        flux_msg_t *msg;
        while ((msg = zlist_pop (p->rmmod)))
            flux_msg_destroy (msg);
    }
    if (p->subs) {
        char *s;
        while ((s = zlist_pop (p->subs)))
            free (s);
        zlist_destroy (&p->subs);
    }
    zlist_destroy (&p->rmmod);
    p->magic = ~MODULE_MAGIC;
    free (p);
}
コード例 #20
0
ファイル: dispatch.c プロジェクト: cigolabs/flux-core
static void dispatch_usecount_decr (struct dispatch *d)
{
    flux_msg_handler_t *w;
    if (d && --d->usecount == 0) {
        if (d->handlers) {
            while ((w = zlist_pop (d->handlers))) {
                assert (w->destroyed);
                free_msg_handler (w);
            }
            zlist_destroy (&d->handlers);
        }
        if (d->handlers_new) {
            while ((w = zlist_pop (d->handlers_new))) {
                assert (w->destroyed);
                free_msg_handler (w);
            }
            zlist_destroy (&d->handlers_new);
        }
        flux_watcher_destroy (d->w);
        fastpath_free (&d->norm);
        fastpath_free (&d->group);
        free (d);
    }
}
コード例 #21
0
ファイル: kzutil.c プロジェクト: trws/flux-core
static void attach (flux_t *h, const char *key, bool rawtty, int kzoutflags,
                    int blocksize)
{
    t_kzutil_ctx_t *ctx = xzmalloc (sizeof (*ctx));
    char *name;
    int fdin = dup (STDIN_FILENO);
    struct termios saved_tio;
    flux_reactor_t *r = flux_get_reactor (h);
    flux_watcher_t *w = NULL;

    log_msg ("process attached to %s", key);

    ctx->h = h;
    ctx->blocksize = blocksize;

    /* FIXME: need a ~. style escape sequence to terminate stdin
     * in raw mode.
     */
    if (rawtty) {
        if (fd_set_raw (fdin, &saved_tio, true) < 0)
            log_err_exit ("fd_set_raw stdin");
    }
    if (fd_set_nonblocking (fdin, true) < 0)
        log_err_exit ("fd_set_nonblocking stdin");

    if (asprintf (&name, "%s.stdin", key) < 0)
        oom ();
    if (!(ctx->kz[0] = kz_open (h, name, kzoutflags)))
        if (errno == EEXIST)
            log_err ("disabling stdin");
        else
            log_err_exit ("%s", name);
    else {
        if (!(w = flux_fd_watcher_create (r, fdin, FLUX_POLLIN,
                                attach_stdin_ready_cb, ctx)))
            log_err_exit ("flux_fd_watcher_create %s", name);
        flux_watcher_start (w);
    }
    free (name);

    if (asprintf (&name, "%s.stdout", key) < 0)
        oom ();
    if (!(ctx->kz[1] = kz_open (h, name, KZ_FLAGS_READ | KZ_FLAGS_NONBLOCK)))
        log_err_exit ("kz_open %s", name);
    if (kz_set_ready_cb (ctx->kz[1], attach_stdout_ready_cb, ctx) < 0)
        log_err_exit ("kz_set_ready_cb %s", name);
    free (name);
    ctx->readers++;

    if (asprintf (&name, "%s.stderr", key) < 0)
        oom ();
    if (!(ctx->kz[2] = kz_open (h, name, KZ_FLAGS_READ | KZ_FLAGS_NONBLOCK)))
        log_err_exit ("kz_open %s", name);
    if (kz_set_ready_cb (ctx->kz[2], attach_stderr_ready_cb, ctx) < 0)
        log_err_exit ("kz_set_ready_cb %s", name);
    free (name);
    ctx->readers++;

    /* Reactor terminates when ctx->readers reaches zero, i.e.
     * when EOF is read from remote stdout and stderr.
     * (Note: if they are already at eof, we will have already terminated
     * before the reactor is started, since kvs_watch callbacks make one
     * call to the callback in the context of the caller).
     */
    if (ctx->readers > 0) {
        if (flux_reactor_run (r, 0) < 0)
            log_err_exit ("flux_reactor_run");
    }

    (void)kz_close (ctx->kz[1]);
    (void)kz_close (ctx->kz[2]);

    /* FIXME: tty state needs to be restored on all exit paths.
     */
    if (rawtty) {
        if (fd_set_raw (fdin, &saved_tio, false) < 0)
            log_err_exit ("fd_set_raw stdin");
    }

    flux_watcher_destroy (w);
    free (ctx);
}
コード例 #22
0
ファイル: zio.c プロジェクト: grondo/flux-core
int main (int argc, char **argv)
{
    zio_t *zio;
    int init_fds;
    const char *name;
    struct counts c;
    int fd;
    flux_reactor_t *r;
    flux_watcher_t *w;

    memset (&c, 0, sizeof (c));

    plan (NO_PLAN);

    test_encode ();

    ok ((r = flux_reactor_create (0)) != NULL,
        "flux reactor created");

    init_fds = fdcount ();
    diag ("initial fd count: %d", init_fds);

    /* simple reader tests
     */
    ok ((zio = zio_pipe_reader_create ("test1", &c)) != NULL,
        "reader: zio_pipe_reader_create works");
    ok ((name = zio_name (zio)) != NULL && !strcmp (name, "test1"),
        "reader: zio_name returns correct name");
    ok (zio_set_close_cb (zio, close_reader) == 0,
        "reader: zio_set_close_cb works");
    ok (zio_set_send_cb (zio, send_reader) == 0,
        "reader: zio_set_send_cb works");
    ok (zio_reactor_attach (zio, r) == 0,
        "reader: zio_reactor_attach works");
    ok ((fd = zio_dst_fd (zio)) >= 0,
        "reader: zio_dst_fd returned valid file descriptor");
    ok (write (fd, "narf!", 5) == 5,
        "reader: wrote narf! to reader pipe");
    ok (zio_close_dst_fd (zio) == 0,
        "reader: zio_close_dst_fd succeeded");
    ok (flux_reactor_run (r, 0) == 0,
        "reader: reactor completed successfully");
    ok (c.send_reader == 1,
        "reader: send function called once for EOF + incomplete line");
    errno = 0;
    zio_destroy (zio);
    ok (init_fds == fdcount (),
        "reader: zio_destroy leaks no file descriptors");

    /* simple writer tests
     */
    ok ((zio = zio_pipe_writer_create ("test2", &c)) != NULL,
        "writer: zio_pipe_writer_create works");
    ok ((name = zio_name (zio)) != NULL && !strcmp (name, "test2"),
        "writer: zio_name returns correct name");
    ok (zio_set_close_cb (zio, close_writer) == 0,
        "writer: zio_set_close_cb works");
    ok ((fd = zio_src_fd (zio)) >= 0,
        "writer: zio_src_fd returned valid file descriptor");
    w = flux_fd_watcher_create (r, fd, FLUX_POLLIN, fd_read, &c);
    ok (w != NULL,
        "writer: created fd watcher");
    flux_watcher_start (w);
    ok (zio_write (zio, "narf!", 5) == 5,
        "writer: zio_write narf! works");
    ok (zio_write_eof (zio) == 0,
        "writer: zio_write_eof works");
    ok (flux_reactor_run (r, 0) == 0,
        "writer: reactor completed successfully");
    ok (c.fd_read_errors == 0 && c.fd_read_data == 5 && c.fd_read_eof == 1,
        "writer: read narf + EOF on read end of pipe");
    ok (c.close_writer == 1,
        "writer: close callback invoked");

    zio_destroy (zio);
    ok (init_fds == fdcount (),
        "writer: zio_destroy leaks no file descriptors");

    flux_watcher_destroy (w);
    flux_reactor_destroy (r);

    done_testing ();
}
コード例 #23
0
ファイル: flux-ping.c プロジェクト: SteVwonder/flux-core
int main (int argc, char *argv[])
{
    int ch;
    int pad_bytes = 0;
    char *target;
    flux_watcher_t *tw = NULL;
    struct ping_ctx ctx = {
        .period = 1.0,
        .rank = NULL,
        .nodeid = FLUX_NODEID_ANY,
        .topic = NULL,
        .pad = NULL,
        .count = -1,
        .send_count = 0,
        .batch = false,
    };

    log_init ("flux-ping");

    while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) {
        switch (ch) {
            case 'h': /* --help */
                usage ();
                break;
            case 'p': /* --pad bytes */
                pad_bytes = strtoul (optarg, NULL, 10);
                break;
            case 'd': /* --delay seconds */
                ctx.period = strtod (optarg, NULL);
                if (ctx.period < 0)
                    usage ();
                break;
            case 'r': /* --rank NODESET  */
                ctx.rank = optarg;
                break;
            case 'c': /* --count N */
                ctx.count = strtoul (optarg, NULL, 10);
                break;
            case 'b': /* --batch-request */
                ctx.batch = true;
                break;
            default:
                usage ();
                break;
        }
    }
    if (optind != argc - 1)
        usage ();
    if (ctx.batch && ctx.count == -1)
        log_msg_exit ("--batch should only be used with --count");
    target = argv[optind++];

    /* Create null terminated pad string for reuse in each message.
     * By default it's the empty string.
     */
    ctx.pad = xzmalloc (pad_bytes + 1);
    memset (ctx.pad, 'p', pad_bytes);

    /* If "rank!" is prepended to the target, and there is no --rank
     * argument, snip it off and set the rank.  If it's just the bare
     * rank, assume the target is "cmb".
     */
    if (ctx.rank == NULL) {
        char *p;
        nodeset_t *ns = NULL;
        if ((p = strchr (target, '!'))) {
            *p++ = '\0';
            ctx.rank = target;
            target = p;
        } else if ((ns = nodeset_create_string (target)) != NULL) {
            ctx.rank = target;
            target = "cmb";
            nodeset_destroy (ns);
        } else if (!strcmp (target, "all")) {
            ctx.rank = target;
            target = "cmb";
        }
    }
    /* Use singleton rpc if there's only one nodeid
     */
    if (ctx.rank != NULL) {
        nodeset_t *ns = nodeset_create_string (ctx.rank);
        if (ns) {
            if (nodeset_count (ns) == 1) {
                ctx.nodeid = nodeset_min (ns);
                ctx.rank = NULL;
            }
            nodeset_destroy (ns);
        }
    }

    ctx.topic = xasprintf ("%s.ping", target);

    if (!(ctx.h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");
    if (!(ctx.reactor = flux_get_reactor (ctx.h)))
        log_err_exit ("flux_get_reactor");

    /* In batch mode, requests are sent before reactor is started
     * to process responses.  o/w requests are set in a timer watcher.
     */
    if (ctx.batch) {
        while (ctx.send_count < ctx.count) {
            send_ping (&ctx);
            usleep ((useconds_t)(ctx.period * 1E6));
        }
    } else {
        tw = flux_timer_watcher_create (ctx.reactor, ctx.period, ctx.period,
                                        timer_cb, &ctx);
        if (!tw)
            log_err_exit ("error creating watchers");
        flux_watcher_start (tw);
    }
    if (flux_reactor_run (ctx.reactor, 0) < 0)
        log_err_exit ("flux_reactor_run");

    /* Clean up.
     */
    flux_watcher_destroy (tw);

    free (ctx.topic);
    free (ctx.pad);

    flux_close (ctx.h);
    log_fini ();

    return 0;
}
コード例 #24
0
int main (int argc, char *argv[])
{
    flux_t *h;
    flux_reactor_t *r;
    int last = -1;
    int ch;
    flux_future_t *f;

    log_init ("commit_order");

    while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) {
        switch (ch) {
            case 'h': /* --help */
                usage ();
                break;
            case 'v': /* --verbose */
                verbose = true;
                break;
            case 'c': /* --count N */
                totcount = strtoul (optarg, NULL, 10);
                break;
            case 'f': /* --fanout N */
                max_queue_depth = strtoul (optarg, NULL, 10);
                break;
            case 'n': /* --namespace=NAME */
                if (!(ns = strdup (optarg)))
                    log_err_exit ("out of memory");
                break;
            default:
                usage ();
                break;
        }
    }
    if (optind != argc - 1)
        usage ();
    key = argv[optind++];
    if (totcount < 1 || max_queue_depth < 1)
        usage ();

    if (!(h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");
    if (!(r = flux_get_reactor (h)))
        log_err_exit ("flux_get_reactor");
    /* One synchronous put before watch request, so that
     * watch request doesn't fail with ENOENT.
     */
    f = commit_int (h, key, txcount++);
    commit_continuation (f, NULL); // destroys f, increments rxcount

    /* Configure watcher
     * Wait for one response before unleashing async puts, to ensure
     * that first value is captured.
     */
    if (!(f = flux_kvs_lookup (h, ns, FLUX_KVS_WATCH, key)))
        log_err_exit ("flux_kvs_lookup");
    watch_continuation (f, &last); // resets f, increments wrxcount
    if (flux_future_then (f, -1., watch_continuation, &last) < 0)
        log_err_exit ("flux_future_then");

    /* Configure mechanism to keep max_queue_depth (--fanout) put RPCs
     * outstanding until totcount (--count) reached.
     */
    if (!(w_prep = flux_prepare_watcher_create (r, prep, NULL)))
        log_err_exit ("flux_prepare_watcher_create");
    if (!(w_check = flux_check_watcher_create (r, check, h)))
        log_err_exit ("flux_check_watcher_create");
    if (!(w_idle = flux_idle_watcher_create (r, NULL, NULL)))
        log_err_exit ("flux_idle_watcher_create");
    flux_watcher_start (w_prep);
    flux_watcher_start (w_check);

    /* Run until work is exhausted.
     */
    if (flux_reactor_run (r, 0) < 0)
        log_err_exit ("flux_reactor_run");

    flux_watcher_destroy (w_prep);
    flux_watcher_destroy (w_check);
    flux_watcher_destroy (w_idle);

    free (ns);
    flux_close (h);
    log_fini ();
    return 0;
}