Exemple #1
0
static int op_send (void *impl, const flux_msg_t *msg, int flags)
{
    ctx_t *c = impl;
    assert (c->magic == CTX_MAGIC);
    int type;
    flux_msg_t *cpy = NULL;
    int rc = -1;

    if (!(cpy = flux_msg_copy (msg, true)))
        goto done;
    if (flux_msg_get_type (cpy, &type) < 0)
        goto done;
    switch (type) {
        case FLUX_MSGTYPE_REQUEST:
        case FLUX_MSGTYPE_EVENT:
            if (flux_msg_enable_route (cpy) < 0)
                goto done;
            if (flux_msg_push_route (cpy, fake_uuid) < 0)
                goto done;
            break;
    }
    if (msglist_append (c->queue, cpy) < 0)
        goto done;
    cpy = NULL; /* c->queue now owns cpy */
    rc = 0;
done:
    if (cpy)
        flux_msg_destroy (cpy);
    return rc;
}
Exemple #2
0
static void disconnect_destroy (client_t *c, struct disconnect_notify *d)
{
    flux_msg_t *msg;

    if (!(msg = flux_msg_create (FLUX_MSGTYPE_REQUEST)))
        goto done;
    if (flux_msg_set_topic (msg, d->topic) < 0)
        goto done;
    if (flux_msg_enable_route (msg) < 0)
        goto done;
    if (flux_msg_push_route (msg, zuuid_str (c->uuid)) < 0)
        goto done;
    if (flux_msg_set_nodeid (msg, d->nodeid, d->flags) < 0)
        goto done;
    (void)flux_send (c->ctx->h, msg, 0);
done:
    flux_msg_destroy (msg);
    free (d->topic);
    free (d);
}
Exemple #3
0
int module_sendmsg (module_t *p, const flux_msg_t *msg)
{
    flux_msg_t *cpy = NULL;
    int type;
    int rc = -1;

    if (!msg)
        return 0;
    if (flux_msg_get_type (msg, &type) < 0)
        goto done;
    switch (type) {
        case FLUX_MSGTYPE_REQUEST: { /* simulate DEALER socket */
            char uuid[16];
            snprintf (uuid, sizeof (uuid), "%u", p->rank);
            if (!(cpy = flux_msg_copy (msg, true)))
                goto done;
            if (flux_msg_push_route (cpy, uuid) < 0)
                goto done;
            if (flux_msg_sendzsock (p->sock, cpy) < 0)
                goto done;
            break;
        }
        case FLUX_MSGTYPE_RESPONSE: { /* simulate ROUTER socket */
            if (!(cpy = flux_msg_copy (msg, true)))
                goto done;
            if (flux_msg_pop_route (cpy, NULL) < 0)
                goto done;
            if (flux_msg_sendzsock (p->sock, cpy) < 0)
                goto done;
            break;
        }
        default:
            if (flux_msg_sendzsock (p->sock, msg) < 0)
                goto done;
            break;
    }
    rc = 0;
done:
    flux_msg_destroy (cpy);
    return rc;
}
Exemple #4
0
static int op_send (void *impl, const flux_msg_t *msg, int flags)
{
    ctx_t *ctx = impl;
    assert (ctx->magic == MODHANDLE_MAGIC);
    flux_msg_t *cpy = NULL;
    int type;
    int rc = -1;

    if (connect_socket (ctx) < 0)
        goto done;
    if (flux_msg_get_type (msg, &type) < 0)
        goto done;
    switch (type) {
    case FLUX_MSGTYPE_REQUEST:
    case FLUX_MSGTYPE_EVENT:
        if (!(cpy = flux_msg_copy (msg, true)))
            goto done;
        if (flux_msg_enable_route (cpy) < 0)
            goto done;
        if (flux_msg_push_route (cpy, ctx->uuid) < 0)
            goto done;
        if (flux_msg_sendzsock (ctx->sock, cpy) < 0)
            goto done;
        break;
    case FLUX_MSGTYPE_RESPONSE:
    case FLUX_MSGTYPE_KEEPALIVE:
        if (flux_msg_sendzsock (ctx->sock, msg) < 0)
            goto done;
        break;
    default:
        errno = EINVAL;
        goto done;
    }
    rc = 0;
done:
    flux_msg_destroy (cpy);
    return rc;
}
Exemple #5
0
static void client_read_cb (flux_t h, flux_fd_watcher_t *w, int fd,
                            int revents, void *arg)
{
    client_t *c = arg;
    flux_msg_t *msg = NULL;
    int type;

    if (revents & FLUX_POLLERR)
        goto disconnect;
    if (!(revents & FLUX_POLLIN))
        return;
    /* EPROTO, ECONNRESET are normal disconnect errors
     * EWOULDBLOCK, EAGAIN stores state in c->inbuf for continuation
     */
    //flux_log (h, LOG_DEBUG, "recv: client ready");
    if (!(msg = flux_msg_recvfd (c->fd, &c->inbuf))) {
        if (errno == EWOULDBLOCK || errno == EAGAIN) {
            //flux_log (h, LOG_DEBUG, "recv: client not ready");
            return;
        }
        if (errno != ECONNRESET && errno != EPROTO)
            flux_log (h, LOG_ERR, "flux_msg_recvfd: %s", strerror (errno));
        goto disconnect;
    }
    if (flux_msg_get_type (msg, &type) < 0) {
        flux_log (h, LOG_ERR, "flux_msg_get_type: %s", strerror (errno));
        goto disconnect;
    }
    switch (type) {
        const char *name;
        subscription_t *sub;
        case FLUX_MSGTYPE_REQUEST:
            if (match_substr (msg, "api.event.subscribe.", &name)) {
                sub = subscription_create (h, FLUX_MSGTYPE_EVENT, name);
                if (zlist_append (c->subscriptions, sub) < 0)
                    oom ();
            } else if (match_substr (msg, "api.event.unsubscribe.", &name)) {
                if ((sub = subscription_lookup (c, FLUX_MSGTYPE_EVENT, name)))
                    zlist_remove (c->subscriptions, sub);
            } else {
                /* insert disconnect notifier before forwarding request */
                if (c->disconnect_notify && disconnect_update (c, msg) < 0) {
                    flux_log (h, LOG_ERR, "disconnect_update:  %s",
                              strerror (errno));
                    goto disconnect;
                }
                if (flux_msg_push_route (msg, zuuid_str (c->uuid)) < 0)
                    oom (); /* FIXME */
                if (flux_send (h, msg, 0) < 0)
                    err ("%s: flux_send", __FUNCTION__);
            }
            break;
        case FLUX_MSGTYPE_EVENT:
            if (flux_send (h, msg, 0) < 0)
                err ("%s: flux_send", __FUNCTION__);
            break;
        default:
            flux_log (h, LOG_ERR, "drop unexpected %s",
                      flux_msg_typestr (type));
            break;
    }
    flux_msg_destroy (msg);
    return;
disconnect:
    flux_msg_destroy (msg);
    zlist_remove (c->ctx->clients, c);
    client_destroy (c);
}
Exemple #6
0
int main (int argc, char *argv[])
{
    waitqueue_t *q;
    waitqueue_t *q2;
    wait_t *w;
    flux_msg_t *msg;
    int count = 0;
    int i;

    plan (NO_PLAN);

    q = wait_queue_create ();
    q2 = wait_queue_create ();
    ok (q && q2,
        "wait_queue_create works");
    ok (wait_queue_length (q) == 0 && wait_queue_length (q2) == 0,
        "wait_queue_length on brandnew waitqueue_t returns zero");

    msg = flux_msg_create (FLUX_MSGTYPE_REQUEST);
    ok (msg != NULL,
        "flux_msg_create works");
    w = wait_create (NULL, NULL, msg, msghand, &count);
    ok (w != NULL,
        "wait_create works");
    flux_msg_destroy (msg);

    wait_addqueue (q, w);
    wait_addqueue (q2, w);
    ok (wait_queue_length (q) == 1 && wait_queue_length (q2) == 1,
        "wait_addqueue can add wait_t to a two queues");
    wait_runqueue (q);
    ok (wait_queue_length (q) == 0 && wait_queue_length (q2) == 1,
        "wait_runqueue dequeued wait_t from first queue");
    wait_runqueue (q2);
    ok (wait_queue_length (q) == 0 && wait_queue_length (q2) == 0,
        "wait_runqueue dequeued wait_t from second queue");
    ok (count == 1,
        "wait_runqueue ran the wait_t once");

    for (i = 0; i < 20; i++) {
        char *s = xasprintf ("%d", i);
        msg = flux_msg_create (FLUX_MSGTYPE_REQUEST);
        if (!msg)
            break;
        if (flux_msg_enable_route (msg) < 0
            || flux_msg_push_route (msg, s) < 0)
            break;
        w = wait_create (NULL, NULL, msg, msghand, &count);
        if (!w)
            break;
        wait_addqueue (q, w);
        free (s);
    }
    ok (wait_queue_length (q) == 20,
        "wait_addqueue 20x works");
    wait_destroy_match (q, msgcmp, NULL);
    ok (wait_queue_length (q) == 17,
        "wait_destroy_match on sender works");
    wait_destroy_match (q, msgcmp2, NULL);
    ok (wait_queue_length (q) == 0,
        "all-match wait_destroy_match works");

    wait_queue_destroy (q);
    wait_queue_destroy (q2);

    done_testing ();
    return (0);
}