void messaging_adapter::on_link_flow(proton_event &pe) {
    pn_event_t *pne = pe.pn_event();
    pn_link_t *lnk = pn_event_link(pne);
    // TODO: process session flow data, if no link-specific data, just return.
    if (!lnk) return;
    link_context& lctx = link_context::get(lnk);
    int state = pn_link_state(lnk);
    if ((state&PN_LOCAL_ACTIVE) && (state&PN_REMOTE_ACTIVE)) {
        if (pn_link_is_sender(lnk)) {
            if (pn_link_credit(lnk) > 0) {
                sender s(make_wrapper<sender>(lnk));
                if (pn_link_get_drain(lnk)) {
                    if (!lctx.draining) {
                        lctx.draining = true;
                        delegate_.on_sender_drain_start(s);
                    }
                }
                else {
                    lctx.draining = false;
                }
                // create on_message extended event
                delegate_.on_sendable(s);
            }
        }
        else {
            // receiver
            if (!pn_link_credit(lnk) && lctx.draining) {
                lctx.draining = false;
                receiver r(make_wrapper<receiver>(lnk));
                delegate_.on_receiver_drain_finish(r);
            }
        }
    }
    credit_topup(lnk);
}
Ejemplo n.º 2
0
qd_link_t *qd_link(qd_node_t *node, qd_connection_t *conn, qd_direction_t dir, const char* name)
{
    qd_link_t *link = new_qd_link_t();

    link->pn_sess = pn_session(qd_connection_pn(conn));
    pn_session_set_incoming_capacity(link->pn_sess, 1000000);

    if (dir == QD_OUTGOING)
        link->pn_link = pn_sender(link->pn_sess, name);
    else
        link->pn_link = pn_receiver(link->pn_sess, name);

    link->direction  = dir;
    link->context    = node->context;
    link->node       = node;
    link->drain_mode = pn_link_get_drain(link->pn_link);
    link->remote_snd_settle_mode = pn_link_remote_snd_settle_mode(link->pn_link);
    link->close_sess_with_link = true;

    //
    // Keep the borrowed references
    //
    pn_incref(link->pn_link);
    pn_incref(link->pn_sess);

    pn_link_set_context(link->pn_link, link);

    pn_session_open(link->pn_sess);

    return link;
}
Ejemplo n.º 3
0
bool qd_link_drain_changed(qd_link_t *link, bool *mode)
{
    bool pn_mode = pn_link_get_drain(link->pn_link);
    bool changed = pn_mode != link->drain_mode;

    *mode = pn_mode;
    if (changed)
        link->drain_mode = pn_mode;
    return changed;
}
Ejemplo n.º 4
0
static void setup_outgoing_link(qd_container_t *container, pn_link_t *pn_link)
{
    sys_mutex_lock(container->lock);
    qd_node_t  *node = 0;
    const char *source = pn_terminus_get_address(pn_link_remote_source(pn_link));
    qd_field_iterator_t *iter;
    // TODO - Extract the name from the structured source

    if (source) {
        iter   = qd_address_iterator_string(source, ITER_VIEW_NODE_ID);
        qd_hash_retrieve(container->node_map, iter, (void*) &node);
        qd_field_iterator_free(iter);
    }
    sys_mutex_unlock(container->lock);

    if (node == 0) {
        if (container->default_node)
            node = container->default_node;
        else {
            pn_condition_t *cond = pn_link_condition(pn_link);
            pn_condition_set_name(cond, "amqp:not-found");
            pn_condition_set_description(cond, "Source node does not exist");
            pn_link_close(pn_link);
            return;
        }
    }

    qd_link_t *link = new_qd_link_t();
    if (!link) {
        pn_condition_t *cond = pn_link_condition(pn_link);
        pn_condition_set_name(cond, "amqp:internal-error");
        pn_condition_set_description(cond, "Insufficient memory");
        pn_link_close(pn_link);
        return;
    }

    link->pn_sess    = pn_link_session(pn_link);
    link->pn_link    = pn_link;
    link->direction  = QD_OUTGOING;
    link->context    = 0;
    link->node       = node;

    link->remote_snd_settle_mode = pn_link_remote_snd_settle_mode(pn_link);
    link->drain_mode             = pn_link_get_drain(pn_link);
    link->close_sess_with_link   = false;

    //
    // Keep the borrowed references
    //
    pn_incref(pn_link);
    pn_incref(link->pn_sess);

    pn_link_set_context(pn_link, link);
    node->ntype->outgoing_handler(node->context, link);
}
Ejemplo n.º 5
0
/**
 * Handler for flow events on links
 */
static int AMQP_link_flow_handler(void* context, qd_link_t *link)
{
    qd_router_t *router = (qd_router_t*) context;
    qdr_link_t  *rlink  = (qdr_link_t*) qd_link_get_context(link);
    pn_link_t   *pnlink = qd_link_pn(link);

    if (!rlink)
        return 0;

    qdr_link_flow(router->router_core, rlink, pn_link_remote_credit(pnlink), pn_link_get_drain(pnlink));

    return 0;
}