Esempio n. 1
0
static flux_msg_handler_t *find_waiting_handler (struct dispatch *d,
                                                 const flux_msg_t *msg)
{
    flux_msg_handler_t *w = zlist_first (d->waiters);
    while (w) {
        if (flux_msg_cmp (msg, w->wait_match))
            break;
        w = zlist_next (d->waiters);
    }
    return w;
}
Esempio n. 2
0
/* Free matchtag, first deleting any queued matching responses.
 */
void flux_matchtag_free (flux_t h, uint32_t matchtag)
{
    struct flux_match match = {
        .typemask = FLUX_MSGTYPE_RESPONSE,
        .topic_glob = NULL,
        .matchtag = matchtag,
    };
    flux_msg_t *msg = msglist_first (h->queue);
    while (msg) {
        if (flux_msg_cmp (msg, match)) {
            msglist_remove (h->queue, msg);
            flux_msg_destroy (msg);
        }
        msg = msglist_next (h->queue);
    }
    tagpool_free (h->tagpool, matchtag);
}
Esempio n. 3
0
/* If this function is called without the NONBLOCK flag from a reactor
 * handler running in coprocess context, the call to flux_sleep_on()
 * will allow the reactor to run until a message matching 'match' arrives.
 * The flux_sleep_on() call will then resume, and the next call to recv()
 * will return the matching message.  If not running in coprocess context,
 * flux_sleep_on() will fail with EINVAL.  In that case, the do loop
 * reading messages and comparing them to match criteria may have to read
 * a few non-matching messages before finding a match.  On return, those
 * non-matching messages have to be requeued in the handle, hence the
 * defer_*() helper calls.
 */
flux_msg_t *flux_recv (flux_t h, struct flux_match match, int flags)
{
    zlist_t *l = NULL;
    flux_msg_t *msg = NULL;
    int saved_errno;

    flags |= h->flags;
    if (!(flags & FLUX_O_NONBLOCK) && (flags & FLUX_O_COPROC) &&
        flux_sleep_on (h, match) < 0) {
        if (errno != EINVAL)
            goto fatal;
        errno = 0;
    }
    do {
        if (!(msg = flux_recv_any (h, flags))) {
            if (errno != EAGAIN && errno != EWOULDBLOCK)
                goto fatal;
            if (defer_requeue (&l, h) < 0)
                goto fatal;
            defer_destroy (&l);
            errno = EWOULDBLOCK;
            return NULL;
        }
        if (!flux_msg_cmp (msg, match)) {
            if (defer_enqueue (&l, msg) < 0)
                goto fatal;
            msg = NULL;
        }
    } while (!msg);
    update_rx_stats (h, msg);
    if ((flags & FLUX_O_TRACE))
        flux_msg_fprint (stderr, msg);
    if (defer_requeue (&l, h) < 0)
        goto fatal;
    defer_destroy (&l);
#if HAVE_CALIPER
    cali_begin_int (h->prof.msg_match_type, match.typemask);
    cali_begin_int (h->prof.msg_match_tag, match.matchtag);
    cali_begin_string (h->prof.msg_match_glob,
                       match.topic_glob ? match.topic_glob : "NONE");
    char *sender = NULL;
    flux_msg_get_route_first (msg, &sender);
    if (sender)
        cali_begin_string (h->prof.msg_sender, sender);
    profiling_msg_snapshot (h, msg, flags, "recv");
    if (sender)
        cali_end (h->prof.msg_sender);
    cali_end (h->prof.msg_match_type);
    cali_end (h->prof.msg_match_tag);
    cali_end (h->prof.msg_match_glob);

    free (sender);
#endif
    return msg;
fatal:
    saved_errno = errno;
    FLUX_FATAL (h);
    if (msg)
        flux_msg_destroy (msg);
    defer_destroy (&l);
    errno = saved_errno;
    return NULL;
}