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; }
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); }
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; }
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; }
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); }
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); }