コード例 #1
0
ファイル: treq.c プロジェクト: trws/flux-core
void test_nsrc (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    const int count = 10000;
    json_object *in = Jnew ();
    const char *json_str;
    json_object *out = NULL;
    int i, seq;

    Jadd_int (in, "count", count);
    if (!(f = flux_rpc (h, "req.nsrc", Jtostr (in), FLUX_NODEID_ANY,
                                                      FLUX_RPC_NORESPONSE)))
        log_err_exit ("%s", __FUNCTION__);
    flux_future_destroy (f);
    for (i = 0; i < count; i++) {
        flux_msg_t *msg = flux_recv (h, FLUX_MATCH_ANY, 0);
        if (!msg)
            log_err_exit ("%s", __FUNCTION__);
        if (flux_response_decode (msg, NULL, &json_str) < 0)
            log_msg_exit ("%s: decode %d", __FUNCTION__, i);
        if (!json_str
            || !(out = Jfromstr (json_str))
            || !Jget_int (out, "seq", &seq))
            log_msg_exit ("%s: decode %d payload", __FUNCTION__, i);
        if (seq != i)
            log_msg_exit ("%s: decode %d - seq mismatch %d", __FUNCTION__, i, seq);
        Jput (out);
        flux_msg_destroy (msg);
    }
    Jput (in);
}
コード例 #2
0
ファイル: barrier.c プロジェクト: SteVwonder/flux-core
static void exit_event_cb (flux_t *h, flux_msg_handler_t *w,
                           const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    barrier_t *b;
    const char *json_str;
    json_object *o = NULL;
    const char *name;
    int errnum;

    if (flux_event_decode (msg, NULL, &json_str) < 0) {
        flux_log_error (h, "%s: decoding event", __FUNCTION__);
        goto done;
    }
    if (!(o = Jfromstr (json_str))
                || !Jget_str (o, "name", &name)
                || !Jget_int (o, "errnum", &errnum)) {
        errno = EPROTO;
        flux_log_error (h, "%s: decoding event", __FUNCTION__);
        goto done;
    }
    if ((b = zhash_lookup (ctx->barriers, name))) {
        b->errnum = errnum;
        zhash_foreach (b->clients, send_enter_response, b);
        zhash_delete (ctx->barriers, name);
    }
done:
    Jput (o);
}
コード例 #3
0
ファイル: req.c プロジェクト: dinesh121991/flux-core
/* Return 'n' sequenced responses.
 */
static int nsrc_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    JSON o = Jnew ();
    int i, count;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "count", &count)) {
        if (flux_err_respond (h, EPROTO, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    for (i = 0; i < count; i++) {
        zmsg_t *cpy = zmsg_dup (*zmsg);
        if (!cpy)
            oom ();
        Jadd_int (o, "seq", i);
        if (flux_json_respond (h, o, &cpy) < 0)
            flux_log (h, LOG_ERR, "%s: flux_json_respond: %s", __FUNCTION__,
                      strerror (errno));
        zmsg_destroy (&cpy);
    }
    zmsg_destroy (zmsg);
done:
    Jput (o);
    return 0;
}
コード例 #4
0
ファイル: req.c プロジェクト: cigolabs/flux-core
/* Return 'n' sequenced responses.
 */
void nsrc_request_cb (flux_t h, flux_msg_handler_t *w,
                      const flux_msg_t *msg, void *arg)
{
    const char *json_str;
    int saved_errno;
    JSON o = Jnew ();
    int i, count;
    int rc = -1;

    if (flux_request_decode (msg, NULL, &json_str) < 0) {
        saved_errno = errno;
        goto done;
    }
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "count", &count)) {
        saved_errno = errno = EPROTO;
        goto done;
    }
    for (i = 0; i < count; i++) {
        Jadd_int (o, "seq", i);
        if (flux_respond (h, msg, 0, Jtostr (o)) < 0) {
            saved_errno = errno;
            flux_log_error (h, "%s: flux_respond", __FUNCTION__);
            goto done;
        }
    }
    rc = 0;
done:
    if (rc < 0) {
        if (flux_respond (h, msg, saved_errno, NULL) < 0)
            flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    }
    Jput (o);
}
コード例 #5
0
ファイル: flux-ping.c プロジェクト: SteVwonder/flux-core
/* Handle responses
 */
void ping_continuation (flux_rpc_t *rpc, void *arg)
{
    struct ping_ctx *ctx = arg;
    const char *json_str, *route, *pad;
    int64_t sec, nsec;
    struct timespec t0;
    int seq;
    json_object *out = NULL;
    struct ping_data *pdata = flux_rpc_aux_get (rpc);
    tstat_t *tstat = pdata->tstat;

    if (flux_rpc_get (rpc, &json_str) < 0) {
        log_err ("flux_rpc_get");
        goto done;
    }
    if (!(out = Jfromstr (json_str))
            || !Jget_int (out, "seq", &seq)
            || !Jget_int64 (out, "time.tv_sec", &sec)
            || !Jget_int64 (out, "time.tv_nsec", &nsec)
            || !Jget_str (out, "pad", &pad)
            || !Jget_str (out, "route", &route)
            || strcmp (ctx->pad, pad) != 0) {
        log_err ("error decoding ping response");
        goto done;
    }
    t0.tv_sec = sec;
    t0.tv_nsec = nsec;
    tstat_push (tstat, monotime_since (t0));

    pdata->seq = seq;
    if (pdata->route)
        free (pdata->route);
    pdata->route = xstrdup (route);
    pdata->rpc_count++;

done:
    if (flux_rpc_next (rpc) < 0 && pdata->rpc_count) {
        if (ctx->rank != NULL) {
            printf ("%s!%s pad=%lu seq=%d time=(%0.3f:%0.3f:%0.3f) ms stddev %0.3f\n",
                    ctx->rank,
                    ctx->topic, strlen (ctx->pad), pdata->seq,
                    tstat_min (tstat), tstat_mean (tstat), tstat_max (tstat),
                    tstat_stddev (tstat));
        } else {
            char s[16];
            snprintf (s, sizeof (s), "%u", ctx->nodeid);
            printf ("%s%s%s pad=%lu seq=%d time=%0.3f ms (%s)\n",
                    ctx->nodeid == FLUX_NODEID_ANY ? "" : s,
                    ctx->nodeid == FLUX_NODEID_ANY ? "" : "!",
                    ctx->topic, strlen (ctx->pad), pdata->seq,
                    tstat_mean (tstat),
                    pdata->route);
        }
        flux_rpc_destroy (rpc);
    }
    Jput (out);
}
コード例 #6
0
ファイル: treq.c プロジェクト: trws/flux-core
/* This test is to make sure that deferred responses are handled in order.
 * Arrange for module to source 10K sequenced responses.  Messages 5000-5499
 * are "put back" on the handle using flux_putmsg().  We ensure that
 * the 10K messages are nonetheless received in order.
 */
void test_putmsg (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    const char *json_str;
    const int count = 10000;
    const int defer_start = 5000;
    const int defer_count = 500;
    json_object *in = Jnew ();
    json_object *out = NULL;
    int seq, myseq = 0;
    zlist_t *defer = zlist_new ();
    bool popped = false;
    flux_msg_t *z;

    if (!defer)
        oom ();

    Jadd_int (in, "count", count);
    if (!(f = flux_rpc (h, "req.nsrc", Jtostr (in), FLUX_NODEID_ANY,
                                                      FLUX_RPC_NORESPONSE)))
        log_err_exit ("%s", __FUNCTION__);
    flux_future_destroy (f);
    do {
        flux_msg_t *msg = flux_recv (h, FLUX_MATCH_ANY, 0);
        if (!msg)
            log_err_exit ("%s", __FUNCTION__);
        if (flux_response_decode (msg, NULL, &json_str) < 0)
            log_msg_exit ("%s: decode", __FUNCTION__);
        if (!json_str
            || !(out = Jfromstr (json_str))
            || !Jget_int (out, "seq", &seq))
            log_msg_exit ("%s: decode - payload", __FUNCTION__);
        Jput (out);
        if (seq >= defer_start && seq < defer_start + defer_count && !popped) {
            if (zlist_append (defer, msg) < 0)
                oom ();
            if (seq == defer_start + defer_count - 1) {
                while ((z = zlist_pop (defer))) {
                    if (flux_requeue (h, z, FLUX_RQ_TAIL) < 0)
                        log_err_exit ("%s: flux_requeue", __FUNCTION__);
                    flux_msg_destroy (z);
                }
                popped = true;
            }
            continue;
        }
        if (seq != myseq)
            log_msg_exit ("%s: expected %d got %d", __FUNCTION__, myseq, seq);
        myseq++;
        flux_msg_destroy (msg);
    } while (myseq < count);
    zlist_destroy (&defer);
    Jput (in);
}
コード例 #7
0
ファイル: req.c プロジェクト: cigolabs/flux-core
/* Proxy ping.
 */
void xping_request_cb (flux_t h, flux_msg_handler_t *w,
                       const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    const char *json_str;
    int saved_errno;
    int rank, seq = ctx->ping_seq++;
    const char *service;
    char *hashkey = NULL;
    JSON in = Jnew ();
    JSON o = NULL;
    flux_msg_t *cpy;

    if (flux_request_decode (msg, NULL, &json_str) < 0) {
        saved_errno = errno;
        goto error;
    }
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "rank", &rank)
                                   || !Jget_str (o, "service", &service)) {
        saved_errno = errno = EPROTO;
        goto error;
    }
    flux_log (h, LOG_DEBUG, "Rxping rank=%d service=%s", rank, service);

    Jadd_int (in, "seq", seq);
    flux_log (h, LOG_DEBUG, "Tping seq=%d %d!%s", seq, rank, service);

    flux_rpc_t *rpc;
    if (!(rpc = flux_rpc (h, service, Jtostr (in), rank,
                                            FLUX_RPC_NORESPONSE))) {
        saved_errno = errno;
        goto error;
    }
    flux_rpc_destroy (rpc);
    if (!(cpy = flux_msg_copy (msg, true))) {
        saved_errno = errno;
        goto error;
    }
    hashkey = xasprintf ("%d", seq);
    zhash_update (ctx->ping_requests, hashkey, cpy);
    zhash_freefn (ctx->ping_requests, hashkey, (zhash_free_fn *)flux_msg_destroy);
    Jput (o);
    Jput (in);
    if (hashkey)
        free (hashkey);
    return;
error:
    if (flux_respond (h, msg, saved_errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    Jput (o);
    Jput (in);
}
コード例 #8
0
ファイル: trpc.c プロジェクト: dinesh121991/flux-core
void get_rank (flux_rpc_t *rpc)
{
    const char *json_str;
    JSON o;
    int rank;

    if (flux_rpc_get (rpc, NULL, &json_str) < 0)
        err_exit ("flux_rpc_get");
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "rank", &rank))
        msg_exit ("response protocol error");
    printf ("rank is %d\n", rank);
    Jput (o);
}
コード例 #9
0
ファイル: shutdown.c プロジェクト: cigolabs/flux-core
int shutdown_decode (const flux_msg_t *msg, double *grace, int *exitcode,
                     int *rank, char *reason, int reason_len)
{
    const char *json_str, *s;
    JSON in = NULL;
    int rc = -1;

    if (flux_event_decode (msg, NULL, &json_str) < 0
                || !(in = Jfromstr (json_str))
                || !Jget_str (in, "reason", &s)
                || !Jget_double (in, "grace", grace)
                || !Jget_int (in, "rank", rank)
                || !Jget_int (in, "exitcode", exitcode)) {
        errno = EPROTO;
        goto done;
    }
    snprintf (reason, reason_len, "%s", s);
    rc = 0;
done:
    Jput (in);
    return rc;
}
コード例 #10
0
ファイル: proto.c プロジェクト: cigolabs/flux-core
int kp_rgetroot_dec (JSON o, int *rootseq, const char **rootdir)
{
    int rc = -1;

    if (!rootseq || !rootdir) {
        errno = EINVAL;
        goto done;
    }
    if (!Jget_int (o, "rootseq", rootseq) || !Jget_str (o, "rootdir", rootdir)){
        errno = EPROTO;
        goto done;
    }
    rc = 0;
done:
    return rc;
}
コード例 #11
0
ファイル: hello.c プロジェクト: cigolabs/flux-core
int hello_decode (const flux_msg_t *msg, int *rank)
{
    const char *json_str, *topic_str;
    JSON in = NULL;
    int rc = -1;

    if (flux_request_decode (msg, &topic_str, &json_str) < 0)
        goto done;
    if (!(in = Jfromstr (json_str)) || !Jget_int (in, "rank", rank)
                                    || strcmp (topic_str, "cmb.hello") != 0) {
        errno = EPROTO;
        goto done;
    }
    rc = 0;
done:
    Jput (in);
    return rc;
}
コード例 #12
0
ファイル: treq.c プロジェクト: trws/flux-core
void test_src (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    const char *json_str;
    json_object *out = NULL;
    int i;

    if (!(f = flux_rpc (h, "req.src", NULL, nodeid, 0))
             || flux_rpc_get (f, &json_str) < 0)
        log_err_exit ("%s", __FUNCTION__);
    if (!json_str
        || !(out = Jfromstr (json_str))
        || !Jget_int (out, "wormz", &i)
        || i != 42)
        log_msg_exit ("%s: didn't get expected payload", __FUNCTION__);
    Jput (out);
    flux_future_destroy (f);
}
コード例 #13
0
ファイル: heartbeat.c プロジェクト: cigolabs/flux-core
int flux_heartbeat_decode (const flux_msg_t *msg, int *epoch)
{
    const char *json_str, *topic_str;
    JSON out = NULL;
    int rc = -1;

    if (flux_event_decode (msg, &topic_str, &json_str) < 0)
        goto done;
    if (strcmp (topic_str, "hb") != 0 || !(out = Jfromstr (json_str))
                                      || !Jget_int (out, "epoch", epoch)) {
        errno = EPROTO;
        goto done;
    }
    rc = 0;
done:
    Jput (out);
    return rc;
}
コード例 #14
0
ファイル: req.c プロジェクト: dinesh121991/flux-core
/* Handle ping response for proxy ping.
 */
static int ping_response_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    ctx_t *ctx = arg;
    JSON o = NULL;
    JSON out = Jnew ();;
    int seq;
    const char *route;
    zmsg_t *zreq = NULL;
    char *hashkey = NULL;

    if (flux_json_response_decode (*zmsg, &o) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_json_response_decode: %s",
                  __FUNCTION__, strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "seq", &seq) || !Jget_str (o, "route", &route)) {
        flux_log (h, LOG_ERR, "%s: protocol error", __FUNCTION__);
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Rping seq=%d %s", seq, route);
    hashkey = xasprintf ("%d", seq);
    if (!(zreq = zhash_lookup (ctx->ping_requests, hashkey))) {
        flux_log (h, LOG_ERR, "%s: unsolicited ping response: %s",
                  __FUNCTION__, hashkey);
        goto done;
    }
    zhash_delete (ctx->ping_requests, hashkey);
    flux_log (h, LOG_DEBUG, "Txping seq=%d %s", seq, route);
    Jadd_str (out, "route", route);
    if (flux_json_respond (h, out, &zreq) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_json_respond: %s",
                  __FUNCTION__, strerror (errno));
        goto done;
    }
done:
    if (hashkey)
        free (hashkey);
    Jput (o);
    Jput (out);
    //zmsg_destroy (zmsg);
    zmsg_destroy (&zreq);
    return 0;
}
コード例 #15
0
ファイル: flog.c プロジェクト: cigolabs/flux-core
static int dmesg_rpc_get (flux_rpc_t *rpc, int *seq, flux_log_f fun, void *arg)
{
    const char *json_str;
    const char *buf;
    JSON o = NULL;
    int rc = -1;

    if (flux_rpc_get (rpc, NULL, &json_str) < 0)
        goto done;
    if (!(o = Jfromstr (json_str)) || !Jget_str (o, "buf", &buf)
                                   || !Jget_int (o, "seq", seq)) {
        errno = EPROTO;
        goto done;
    }
    fun (buf, strlen (buf), arg);
    rc = 0;
done:
    Jput (o);
    return rc;
}
コード例 #16
0
ファイル: req.c プロジェクト: dinesh121991/flux-core
/* Proxy ping.
 */
static int xping_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    ctx_t *ctx = arg;
    int rank, seq = ctx->ping_seq++;
    const char *service;
    char *hashkey = NULL;
    JSON in = Jnew ();
    JSON o = NULL;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "rank", &rank) || !Jget_str (o, "service", &service)) {
        if (flux_err_respond (h, EPROTO, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Rxping rank=%d service=%s", rank, service);

    Jadd_int (in, "seq", seq);
    flux_log (h, LOG_DEBUG, "Tping seq=%d %d!%s", seq, rank, service);
    if (flux_json_request (h, rank, 0, service, in) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    hashkey = xasprintf ("%d", seq);
    zhash_update (ctx->ping_requests, hashkey, *zmsg);
    *zmsg = NULL;
done:
    Jput (o);
    Jput (in);
    if (hashkey)
        free (hashkey);
    return 0;
}
コード例 #17
0
ファイル: watch.c プロジェクト: SteVwonder/flux-core
int get_watch_stats (flux_t *h, int *count)
{
    flux_rpc_t *rpc;
    const char *json_str;
    json_object *o = NULL;
    int rc = -1;

    if (!(rpc = flux_rpc (h, "kvs.stats.get", NULL, FLUX_NODEID_ANY, 0)))
        goto done;
    if (flux_rpc_get (rpc, &json_str) < 0)
        goto done;
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "#watchers", count)) {
        errno = EPROTO;
        goto done;
    }
    rc = 0;
done:
    flux_rpc_destroy (rpc);
    Jput (o);
    return rc;
}
コード例 #18
0
ファイル: proto.c プロジェクト: cigolabs/flux-core
int kp_tsetroot_dec (JSON o, int *rootseq, const char **rootdir,
                     JSON *root, const char **fence)
{
    int rc = -1;

    if (!o || !rootseq || !rootdir || !root || !fence) {
        errno = EINVAL;
        goto done;
    }
    if (!Jget_int (o, "rootseq", rootseq) || !Jget_str (o, "rootdir", rootdir)){
        errno = EPROTO;
        goto done;
    }
    *fence = NULL;
    (void)Jget_str (o, "fence", fence);
    *root = NULL;
    (void)Jget_obj (o, "rootdirval", root);
    rc = 0;
done:
    return rc;
}
コード例 #19
0
ファイル: req.c プロジェクト: cigolabs/flux-core
/* Handle ping response for proxy ping.
 * Match it with a request and respond to that request.
 */
void ping_response_cb (flux_t h, flux_msg_handler_t *w,
                       const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    const char *json_str;
    JSON o = NULL;
    JSON out = Jnew ();;
    int seq;
    const char *route;
    flux_msg_t *req = NULL;
    char *hashkey = NULL;

    if (flux_response_decode (msg, NULL, &json_str) < 0) {
        flux_log_error (h, "%s: flux_response_decode", __FUNCTION__);
        goto done;
    }
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "seq", &seq)
                                   || !Jget_str (o, "route", &route)) {
        errno = EPROTO;
        flux_log_error (h, "%s: payload", __FUNCTION__);
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Rping seq=%d %s", seq, route);
    hashkey = xasprintf ("%d", seq);
    if (!(req = zhash_lookup (ctx->ping_requests, hashkey))) {
        flux_log_error (h, "%s: unsolicited ping response", __FUNCTION__);
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Txping seq=%d %s", seq, route);
    Jadd_str (out, "route", route);
    if (flux_respond (h, req, 0, Jtostr (out)) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    zhash_delete (ctx->ping_requests, hashkey);
done:
    if (hashkey)
        free (hashkey);
    Jput (o);
    Jput (out);
}
コード例 #20
0
ファイル: proto.c プロジェクト: surajpkn/flux-core
void test_put (void)
{
    JSON o;
    bool dir = false;
    bool link = false;
    const char *key = NULL;
    JSON val = NULL;
    int i;

    val = Jnew ();
    Jadd_int (val, "i", 2);
    o = kp_tput_enc ("a", val, false, true);
    ok (o != NULL,
        "kp_tput_snec works");
    val = NULL;
    ok (kp_tput_dec (o, &key, &val, &dir, &link) == 0
        && !dir && link,
        "kp_tput_dec works");
    ok (val && Jget_int (val, "i", &i) && i == 2,
        "kp_tput_dec returned encoded object");
    Jput (o); /* owns val */
}
コード例 #21
0
ファイル: proto.c プロジェクト: surajpkn/flux-core
void test_get (void)
{
    JSON o;
    bool dir = false;
    bool link = false;
    const char *key = NULL;
    JSON val = NULL;
    int i;

    o = kp_tget_enc ("foo", false, true);
    ok (o != NULL,
        "kp_tget_enc works");
    ok (kp_tget_dec (o, &key, &dir, &link) == 0 && dir == false && link == true,
        "kp_tget_dec works");
    like (key, "^foo$",
        "kp_tget_dec returned encoded key");
    Jput (o);

    val = Jnew ();
    Jadd_int (val, "i", 42);
    o = kp_rget_enc ("foo", val);
    val = NULL; /* val now owned by o */
    ok (o != NULL,
        "kp_rget_enc works");
    ok (kp_rget_dec (o, &val) == 0,
        "kp_rget_dec works");
    ok (val && Jget_int (val, "i", &i) && i == 42,
        "kp_rget_dec returned encoded object");
    Jput (o); /* owns val */

    o = kp_rget_enc ("foo", NULL);
    ok (o != NULL,
        "kp_rget_enc works with NULL value");
    errno = 0;
    ok (kp_rget_dec (o, &val) < 0 && errno == ENOENT,
        "kp_rget_dec returns error with errno = ENOENT if val is NULL");
    Jput (o);
}
コード例 #22
0
ファイル: proto.c プロジェクト: cigolabs/flux-core
int kp_tcommit_dec (JSON o, const char **sender, JSON *ops,
                    const char **fence, int *nprocs)
{
    int rc = -1;

    if (!sender || !ops || !fence || !nprocs) {
        errno = EINVAL;
        goto done;
    }
    *ops = NULL;
    (void)Jget_obj (o, "ops", ops);
    if (*ops)
        Jget (*ops);
    *sender = NULL;
    (void)Jget_str (o, ".arg_sender", sender);
    *fence = NULL;
    (void)Jget_str (o, ".arg_fence", fence);
    *nprocs = 1;
    (void)Jget_int (o, ".arg_nprocs", nprocs);

    rc = 0;
done:
    return rc;
}
コード例 #23
0
ファイル: cache.c プロジェクト: SteVwonder/flux-core
int main (int argc, char *argv[])
{
    struct cache *cache;
    struct cache_entry *e1, *e2;
    json_object *o1;
    json_object *o2;
    wait_t *w;
    int count, i;

    plan (NO_PLAN);

    cache_destroy (NULL);
    cache_entry_destroy (NULL);
    diag ("cache_destroy and cache_entry_destroy accept NULL arg");

    ok ((cache = cache_create ()) != NULL,
        "cache_create works");
    ok (cache_count_entries (cache) == 0,
        "cache contains 0 entries");
    cache_destroy (cache);

    /* Play with one entry.
     * N.B.: json ref is NOT incremented by create or get_json.
     */
    o1 = Jnew ();
    Jadd_int (o1, "foo", 42);
    ok ((e1 = cache_entry_create (o1)) != NULL,
        "cache_entry_create works");
    ok (cache_entry_get_valid (e1) == true,
        "cache entry initially valid");
    ok (cache_entry_get_dirty (e1) == false,
        "cache entry initially not dirty");
    cache_entry_set_dirty (e1, true);
    ok (cache_entry_get_dirty (e1) == true,
        "cache entry succcessfully set dirty");
    ok ((o2 = cache_entry_get_json (e1)) != NULL,
        "json retrieved from cache entry");
    ok (Jget_int (o2, "foo", &i) == true && i == 42,
        "expected json object found");
    cache_entry_destroy (e1); /* destroys o1 */

    /* Test cache entry waiters.
     * N.B. waiter is destroyed when run.
     */
    count = 0;
    ok ((w = wait_create (wait_cb, &count)) != NULL,
        "wait_create works");
    ok ((e1 = cache_entry_create (NULL)) != NULL,
        "cache_entry_create created empty object");
    ok (cache_entry_get_valid (e1) == false,
        "cache entry invalid, adding waiter");
    o1 = Jnew ();
    Jadd_int (o1, "foo", 42);
    cache_entry_wait_valid (e1, w);
    cache_entry_set_json (e1, o1);
    ok (cache_entry_get_valid (e1) == true,
        "cache entry set valid with one waiter");
    ok (count == 1,
        "waiter callback ran");

    count = 0;
    ok ((w = wait_create (wait_cb, &count)) != NULL,
        "wait_create works");
    cache_entry_set_dirty (e1, true);
    ok (cache_entry_get_dirty (e1) == true,
        "cache entry set dirty, adding waiter");
    cache_entry_wait_notdirty (e1, w);
    cache_entry_set_dirty (e1, false);
    ok (cache_entry_get_dirty (e1) == false,
        "cache entry set not dirty with one waiter");
    ok (count == 1,
        "waiter callback ran");
    cache_entry_destroy (e1); /* destroys o1 */

    /* Put entry in cache and test lookup, expire
     */
    ok ((cache = cache_create ()) != NULL,
        "cache_create works");
    ok (cache_count_entries (cache) == 0,
        "cache contains 0 entries");
    o1 = Jnew ();
    Jadd_int (o1, "foo", 42);
    ok ((e1 = cache_entry_create (o1)) != NULL,
        "cache_entry_create works");
    cache_insert (cache, "xxx1", e1);
    ok (cache_count_entries (cache) == 1,
        "cache contains 1 entry after insert");
    ok (cache_lookup (cache, "yyy1", 0) == NULL,
        "cache_lookup of wrong hash fails");
    ok ((e2 = cache_lookup (cache, "xxx1", 42)) != NULL,
        "cache_lookup of correct hash works (last use=42)");
    i = 0;
    ok ((o2 = cache_entry_get_json (e2)) != NULL
        && Jget_int (o2, "foo", &i) == true && i == 42,
        "expected json object found");
    ok (cache_count_entries (cache) == 1,
        "cache contains 1 entry");
    ok (cache_expire_entries (cache, 43, 1) == 0,
        "cache_expire_entries now=43 thresh=1 expired 0");
    ok (cache_count_entries (cache) == 1,
        "cache contains 1 entry");
    ok (cache_expire_entries (cache, 44, 1) == 1,
        "cache_expire_entries now=44 thresh=1 expired 1");
    ok (cache_count_entries (cache) == 0,
        "cache contains 0 entries");
    cache_destroy (cache);

    done_testing ();
    return (0);
}
コード例 #24
0
ファイル: barrier.c プロジェクト: SteVwonder/flux-core
static void enter_request_cb (flux_t *h, flux_msg_handler_t *w,
                              const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    barrier_t *b;
    json_object *o = NULL;
    char *sender = NULL;
    const char *name;
    int count, nprocs, hopcount;
    const char *json_str;

    if (flux_request_decode (msg, NULL, &json_str) < 0
     		|| flux_msg_get_route_first (msg, &sender) < 0) {
        flux_log_error (ctx->h, "%s: decoding request", __FUNCTION__);
        goto done;
    }
    if (!(o = Jfromstr (json_str))
     	        || !Jget_str (o, "name", &name)
     	        || !Jget_int (o, "count", &count)
     	        || !Jget_int (o, "nprocs", &nprocs)) {
        errno = EPROTO;
        flux_log_error (ctx->h, "%s: decoding request", __FUNCTION__);
        goto done;
    }

    if (!(b = zhash_lookup (ctx->barriers, name)))
        b = barrier_create (ctx, name, nprocs);

    /* Distinguish client (tracked) vs downstream barrier plugin (untracked).
     * A client, distinguished by hopcount > 0, can only enter barrier once.
     */
    if (!Jget_int (o, "hopcount", &hopcount)) {
        if (barrier_add_client (b, sender, msg) < 0) {
            flux_respond (ctx->h, msg, EEXIST, NULL);
            flux_log (ctx->h, LOG_ERR,
                        "abort %s due to double entry by client %s",
                        name, sender);
            if (exit_event_send (ctx->h, b->name, ECONNABORTED) < 0)
                flux_log_error (ctx->h, "exit_event_send");
            goto done;
        }
    }

    /* If the count has been reached, terminate the barrier;
     * o/w set timer to pass count upstream and zero it here.
     */
    b->count += count;
    if (b->count == b->nprocs) {
        if (exit_event_send (ctx->h, b->name, 0) < 0)
            flux_log_error (ctx->h, "exit_event_send");
    } else if (ctx->rank > 0 && !ctx->timer_armed) {
        flux_timer_watcher_reset (ctx->timer, barrier_reduction_timeout_sec, 0.);
        flux_watcher_start (ctx->timer);
        ctx->timer_armed = true;
    }
done:
    if (o)
        json_object_put (o);
    if (sender)
        free (sender);
}
コード例 #25
0
ファイル: simsrv.c プロジェクト: lipari/flux-sched
// Recevied a request to join the simulation ("sim.join")
static void join_cb (flux_t *h,
                     flux_msg_handler_t *w,
                     const flux_msg_t *msg,
                     void *arg)
{
    int mod_rank;
    json_t *request = NULL;
    const char *mod_name = NULL, *json_str = NULL;
    double *next_event = (double *)malloc (sizeof (double));
    ctx_t *ctx = arg;
    sim_state_t *sim_state = ctx->sim_state;
    uint32_t size;

    if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL
        || !(request = Jfromstr (json_str))
        || !Jget_str (request, "mod_name", &mod_name)
        || !Jget_int (request, "rank", &mod_rank)
        || !Jget_double (request, "next_event", next_event)) {
        flux_log (h, LOG_ERR, "%s: bad join message", __FUNCTION__);
        goto out;
    }
    if (flux_get_size (h, &size) < 0)
        goto out;
    if (mod_rank < 0 || mod_rank >= size) {
        flux_log (h, LOG_ERR, "%s: bad rank in join message", __FUNCTION__);
        goto out;
    }

    flux_log (h,
              LOG_DEBUG,
              "join rcvd from module %s on rank %d, next event at %f",
              mod_name,
              mod_rank,
              *next_event);

    zhash_t *timers = sim_state->timers;
    if (zhash_insert (timers, mod_name, next_event) < 0) {  // key already
                                                            // exists
        flux_log (h,
                  LOG_ERR,
                  "duplicate join request from %s, module already exists in "
                  "sim_state",
                  mod_name);
        goto out;
    }
    // clear next event so it is not freed below
    next_event = NULL;

    // TODO: this is horribly hackish, improve the handshake to avoid
    // this hardcoded # of modules. maybe use a timeout?  ZMQ provides
    // support for polling etc with timeouts, should try that
    static int num_modules = 3;
    num_modules--;
    if (num_modules <= 0) {
        if (handle_next_event (ctx) < 0) {
            flux_log (h, LOG_ERR, "failure while handling next event");
            return;
        }
    }

out:
    Jput (request);
    free (next_event);
}