Example #1
0
void qd_message_free(qd_message_t *in_msg)
{
    if (!in_msg) return;
    uint32_t rc;
    qd_message_pvt_t     *msg     = (qd_message_pvt_t*) in_msg;

    qd_buffer_list_free_buffers(&msg->ma_to_override);
    qd_buffer_list_free_buffers(&msg->ma_trace);
    qd_buffer_list_free_buffers(&msg->ma_ingress);

    qd_message_content_t *content = msg->content;

    sys_mutex_lock(content->lock);
    rc = --content->ref_count;
    sys_mutex_unlock(content->lock);

    if (rc == 0) {
        if (content->parsed_message_annotations)
            qd_parse_free(content->parsed_message_annotations);

        qd_buffer_t *buf = DEQ_HEAD(content->buffers);
        while (buf) {
            DEQ_REMOVE_HEAD(content->buffers);
            qd_buffer_free(buf);
            buf = DEQ_HEAD(content->buffers);
        }

        sys_mutex_free(content->lock);
        free_qd_message_content_t(content);
    }

    free_qd_message_t((qd_message_t*) msg);
}
Example #2
0
void qdr_route_connection_opened_CT(qdr_core_t       *core,
                                    qdr_connection_t *conn,
                                    qdr_field_t      *container_field,
                                    qdr_field_t      *connection_field)
{
    if (conn->role != QDR_ROLE_ROUTE_CONTAINER)
        return;

    qdr_conn_identifier_t *cid = qdr_route_declare_id_CT(core,
            container_field?container_field->iterator:0, connection_field?connection_field->iterator:0);

    qdr_add_connection_ref(&cid->connection_refs, conn);

    conn->conn_id        = cid;

    //
    // Activate all link-routes associated with this remote container.
    //
    qdr_link_route_t *lr = DEQ_HEAD(cid->link_route_refs);
    while (lr) {
        qdr_link_route_activate_CT(core, lr, conn);
        lr = DEQ_NEXT_N(REF, lr);
    }

    //
    // Activate all auto-links associated with this remote container.
    //
    qdr_auto_link_t *al = DEQ_HEAD(cid->auto_link_refs);
    while (al) {
        qdr_auto_link_activate_CT(core, al, conn);
        al = DEQ_NEXT_N(REF, al);
    }
}
Example #3
0
void qdr_route_connection_closed_CT(qdr_core_t *core, qdr_connection_t *conn)
{
    if (conn->role != QDR_ROLE_ROUTE_CONTAINER)
        return;

    qdr_conn_identifier_t *cid = conn->conn_id;
    if (cid) {
        //
        // Deactivate all link-routes associated with this remote container.
        //
        qdr_link_route_t *lr = DEQ_HEAD(cid->link_route_refs);
        while (lr) {
            qdr_link_route_deactivate_CT(core, lr, conn);
            lr = DEQ_NEXT_N(REF, lr);
        }

        //
        // Deactivate all auto-links associated with this remote container.
        //
        qdr_auto_link_t *al = DEQ_HEAD(cid->auto_link_refs);
        while (al) {
            qdr_auto_link_deactivate_CT(core, al, conn);
            al = DEQ_NEXT_N(REF, al);
        }

        //
        // Remove our own entry in the connection list
        //
        qdr_del_connection_ref(&cid->connection_refs, conn);

        conn->conn_id        = 0;

        qdr_route_check_id_for_deletion_CT(core, cid);
    }
}
Example #4
0
void qd_connection_manager_start(qd_dispatch_t *qd)
{
    static bool first_start = true;
    qd_listener_t  *li = DEQ_HEAD(qd->connection_manager->listeners);
    qd_connector_t *ct = DEQ_HEAD(qd->connection_manager->connectors);

    while (li) {
        if (!li->pn_listener) {
            if (!qd_listener_listen(li) && first_start) {
                qd_log(qd->connection_manager->log_source, QD_LOG_CRITICAL,
                       "Listen on %s failed during initial config", li->config.host_port);
                exit(1);
            } else {
                li->exit_on_error = first_start;
            }
        }
        li = DEQ_NEXT(li);
    }

    while (ct) {
        qd_connector_connect(ct);
        ct = DEQ_NEXT(ct);
    }

    first_start = false;
}
// get the link route by either name or id
static qdr_link_route_t *_find_link_route_CT(qdr_connection_t *conn,
                                             qd_iterator_t *name, qd_iterator_t *identity)
{
    qdr_link_route_t *lr = NULL;

    // if both id and name provided, prefer id
    //
    if (identity) {
        char buf[64];
        uint64_t id = 0;
        assert(qd_iterator_length(identity) < sizeof(buf));
        qd_iterator_strncpy(identity, buf, sizeof(buf));
        if (sscanf(buf, "%"SCNu64, &id) != 1) {
            return NULL;
        }
        lr = DEQ_HEAD(conn->conn_link_routes);
        while (lr) {
            if (id == lr->identity)
                break;
            lr = DEQ_NEXT(lr);
        }
    } else if (name) {
        lr = DEQ_HEAD(conn->conn_link_routes);
        while (lr) {
            if (qd_iterator_equal(name, (unsigned char *)lr->name))
                break;
            lr = DEQ_NEXT(lr);
        }
    }

    return lr;
}
Example #6
0
void qd_buffer_list_free_buffers(qd_buffer_list_t *list)
{
    qd_buffer_t *buf = DEQ_HEAD(*list);
    while (buf) {
        DEQ_REMOVE_HEAD(*list);
        qd_buffer_free(buf);
        buf = DEQ_HEAD(*list);
    }
}
Example #7
0
static void qd_iterator_free_hash_segments(qd_iterator_t *iter)
{
    qd_hash_segment_t *seg = DEQ_HEAD(iter->hash_segments);
    while (seg) {
        DEQ_REMOVE_HEAD(iter->hash_segments);
        free_qd_hash_segment_t(seg);
        seg = DEQ_HEAD(iter->hash_segments);
    }
}
Example #8
0
void qdr_core_free(qdr_core_t *core)
{
    //
    // Stop and join the thread
    //
    core->running = false;
    sys_cond_signal(core->action_cond);
    sys_thread_join(core->thread);

    //
    // Free the core resources
    //
    sys_thread_free(core->thread);
    sys_cond_free(core->action_cond);
    sys_mutex_free(core->action_lock);
    sys_mutex_free(core->work_lock);
    sys_mutex_free(core->id_lock);
    qd_timer_free(core->work_timer);
    //we can't call qdr_core_unsubscribe on the subscriptions because the action processing thread has
    //already been shut down. But, all the action would have done at this point is free the subscriptions
    //so we just do that directly.
    free(core->agent_subscription_mobile);
    free(core->agent_subscription_local);

    for (int i = 0; i <= QD_TREATMENT_LINK_BALANCED; ++i) {
        if (core->forwarders[i]) {
            free(core->forwarders[i]);
        }
    }

    qdr_address_t *addr = 0;
    while ( (addr = DEQ_HEAD(core->addrs)) ) {
        qdr_core_remove_address(core, addr);
    }
    qdr_address_config_t *addr_config = 0;
    while ( (addr_config = DEQ_HEAD(core->addr_config))) {
        qdr_core_remove_address_config(core, addr_config);
    }
    qd_hash_free(core->addr_hash);

    qd_hash_free(core->conn_id_hash);
    //TODO what about the actual connection identifier objects?

    qdr_node_t *rnode = 0;
    while ( (rnode = DEQ_HEAD(core->routers)) ) {
        qdr_router_node_free(core, rnode);
    }

    if (core->query_lock)                sys_mutex_free(core->query_lock);
    if (core->routers_by_mask_bit)       free(core->routers_by_mask_bit);
    if (core->control_links_by_mask_bit) free(core->control_links_by_mask_bit);
    if (core->data_links_by_mask_bit)    free(core->data_links_by_mask_bit);
    if (core->neighbor_free_mask)        qd_bitmask_free(core->neighbor_free_mask);

    free(core);
}
Example #9
0
void qdr_core_remove_address(qdr_core_t *core, qdr_address_t *addr)
{
    qdr_address_config_t *config = addr->config;
    if (config && --config->ref_count == 0)
        free_address_config(config);

    // Remove the address from the list, hash index, and parse tree
    DEQ_REMOVE(core->addrs, addr);
    if (addr->hash_handle) {
        const char *a_str = (const char *)qd_hash_key_by_handle(addr->hash_handle);
        if (QDR_IS_LINK_ROUTE(a_str[0])) {
            qd_iterator_t *iter = qd_iterator_string(a_str, ITER_VIEW_ALL);
            qdr_link_route_unmap_pattern_CT(core, iter);
            qd_iterator_free(iter);
        }
        qd_hash_remove_by_handle(core->addr_hash, addr->hash_handle);
        qd_hash_handle_free(addr->hash_handle);
    }

    // Free resources associated with this address

    DEQ_APPEND(addr->rlinks, addr->inlinks);
    qdr_link_ref_t *lref = DEQ_HEAD(addr->rlinks);
    while (lref) {
        qdr_link_t *link = lref->link;
        assert(link->owning_addr == addr);
        link->owning_addr = 0;
        qdr_del_link_ref(&addr->rlinks, link, QDR_LINK_LIST_CLASS_ADDRESS);
        lref = DEQ_HEAD(addr->rlinks);
    }

    qd_bitmask_free(addr->rnodes);
    if (addr->treatment == QD_TREATMENT_ANYCAST_CLOSEST) {
        qd_bitmask_free(addr->closest_remotes);
    }
    else if (addr->treatment == QD_TREATMENT_ANYCAST_BALANCED) {
        free(addr->outstanding_deliveries);
    }

    qdr_connection_ref_t *cr = DEQ_HEAD(addr->conns);
    while (cr) {
        qdr_del_connection_ref(&addr->conns, cr->conn);
        cr = DEQ_HEAD(addr->conns);
    }

    if (!!addr->fallback) {
        addr->fallback->fallback_for = 0;
        qdr_check_addr_CT(core, addr->fallback);
    }

    free(addr->add_prefix);
    free(addr->del_prefix);
    free_qdr_address_t(addr);
}
Example #10
0
void qd_connection_manager_free(qd_connection_manager_t *cm)
{
    if (!cm) return;
    qd_listener_t *li = DEQ_HEAD(cm->listeners);
    while (li) {
        DEQ_REMOVE_HEAD(cm->listeners);
        qd_listener_decref(li);
        li = DEQ_HEAD(cm->listeners);
    }

    qd_connector_t *c = DEQ_HEAD(cm->connectors);
    while (c) {
        DEQ_REMOVE_HEAD(cm->connectors);
        qd_connector_decref(c);
        c = DEQ_HEAD(cm->connectors);
    }

    qd_config_ssl_profile_t *sslp = DEQ_HEAD(cm->config_ssl_profiles);
    while (sslp) {
        config_ssl_profile_free(cm, sslp);
        sslp = DEQ_HEAD(cm->config_ssl_profiles);
    }

    qd_config_sasl_plugin_t *saslp = DEQ_HEAD(cm->config_sasl_plugins);
    while (saslp) {
        config_sasl_plugin_free(cm, saslp);
        saslp = DEQ_HEAD(cm->config_sasl_plugins);
    }
}
Example #11
0
File: alloc.c Project: ncdc/qpid
void dx_dealloc(dx_alloc_type_desc_t *desc, dx_alloc_pool_t **tpool, void *p)
{
    item_t          *item = ((item_t*) p) - 1;
    int              idx;

    //
    // If this is the thread's first pass through here, allocate the
    // thread-local pool for this type.
    //
    if (*tpool == 0) {
        *tpool = NEW(dx_alloc_pool_t);
        DEQ_INIT((*tpool)->free_list);
    }

    dx_alloc_pool_t *pool = *tpool;

    DEQ_INSERT_TAIL(pool->free_list, item);

    if (DEQ_SIZE(pool->free_list) <= desc->config->local_free_list_max)
        return;

    //
    // We've exceeded the maximum size of the local free list.  A batch must be
    // rebalanced back to the global list.
    //
    sys_mutex_lock(desc->lock);
    desc->stats->batches_rebalanced_to_global++;
    desc->stats->held_by_threads -= desc->config->transfer_batch_size;
    for (idx = 0; idx < desc->config->transfer_batch_size; idx++) {
        item = DEQ_HEAD(pool->free_list);
        DEQ_REMOVE_HEAD(pool->free_list);
        DEQ_INSERT_TAIL(desc->global_pool->free_list, item);
    }

    //
    // If there's a global_free_list size limit, remove items until the limit is
    // not exceeded.
    //
    if (desc->config->global_free_list_max != 0) {
        while (DEQ_SIZE(desc->global_pool->free_list) > desc->config->global_free_list_max) {
            item = DEQ_HEAD(desc->global_pool->free_list);
            DEQ_REMOVE_HEAD(desc->global_pool->free_list);
            free(item);
            desc->stats->total_free_to_heap++;
        }
    }

    sys_mutex_unlock(desc->lock);
}
Example #12
0
static int writable_handler(qd_container_t *container, pn_connection_t *conn, qd_connection_t* qd_conn)
{
    const qd_node_type_t *nt;
    int                   event_count = 0;

    //
    // Note the locking structure in this function.  Generally this would be unsafe, but since
    // this particular list is only ever appended to and never has items inserted or deleted,
    // this usage is safe in this case.
    //
    sys_mutex_lock(container->lock);
    qdc_node_type_t *nt_item = DEQ_HEAD(container->node_type_list);
    sys_mutex_unlock(container->lock);

    while (nt_item) {
        nt = nt_item->ntype;
        if (nt->writable_handler)
            event_count += nt->writable_handler(nt->type_context, qd_conn, 0);

        sys_mutex_lock(container->lock);
        nt_item = DEQ_NEXT(nt_item);
        sys_mutex_unlock(container->lock);
    }

    return event_count;
}
Example #13
0
qdr_field_t *qdr_field_from_iter(qd_iterator_t *iter)
{
    if (!iter)
        return 0;

    qdr_field_t *field = new_qdr_field_t();
    qd_buffer_t *buf;
    int          remaining;
    int          length;

    ZERO(field);
    qd_iterator_reset(iter);
    remaining = qd_iterator_remaining(iter);
    length    = remaining;
    while (remaining) {
        buf = qd_buffer();
        size_t cap    = qd_buffer_capacity(buf);
        int    copied = qd_iterator_ncopy(iter, qd_buffer_cursor(buf), cap);
        qd_buffer_insert(buf, copied);
        DEQ_INSERT_TAIL(field->buffers, buf);
        remaining = qd_iterator_remaining(iter);
    }

    field->iterator = qd_iterator_buffer(DEQ_HEAD(field->buffers), 0, length, ITER_VIEW_ALL);

    return field;
}
Example #14
0
qdr_field_t *qdr_field(const char *text)
{
    size_t length  = text ? strlen(text) : 0;
    size_t ilength = length;

    if (length == 0)
        return 0;

    qdr_field_t *field = new_qdr_field_t();
    qd_buffer_t *buf;

    ZERO(field);
    while (length > 0) {
        buf = qd_buffer();
        size_t cap  = qd_buffer_capacity(buf);
        size_t copy = length > cap ? cap : length;
        memcpy(qd_buffer_cursor(buf), text, copy);
        qd_buffer_insert(buf, copy);
        length -= copy;
        text   += copy;
        DEQ_INSERT_TAIL(field->buffers, buf);
    }

    field->iterator = qd_iterator_buffer(DEQ_HEAD(field->buffers), 0, ilength, ITER_VIEW_ALL);

    return field;
}
Example #15
0
static void notify_opened(qd_container_t *container, qd_connection_t *conn, void *context)
{
    const qd_node_type_t *nt;

    //
    // Note the locking structure in this function.  Generally this would be unsafe, but since
    // this particular list is only ever appended to and never has items inserted or deleted,
    // this usage is safe in this case.
    //
    sys_mutex_lock(container->lock);
    qdc_node_type_t *nt_item = DEQ_HEAD(container->node_type_list);
    sys_mutex_unlock(container->lock);

    while (nt_item) {
        nt = nt_item->ntype;
        if (qd_connection_inbound(conn)) {
            if (nt->inbound_conn_opened_handler)
                nt->inbound_conn_opened_handler(nt->type_context, conn, context);
        } else {
            if (nt->outbound_conn_opened_handler)
                nt->outbound_conn_opened_handler(nt->type_context, conn, context);
        }

        sys_mutex_lock(container->lock);
        nt_item = DEQ_NEXT(nt_item);
        sys_mutex_unlock(container->lock);
    }
}
Example #16
0
void qd_message_compose_3(qd_message_t *msg, qd_composed_field_t *field1, qd_composed_field_t *field2)
{
    qd_message_content_t *content        = MSG_CONTENT(msg);
    qd_buffer_list_t     *field1_buffers = qd_compose_buffers(field1);
    qd_buffer_list_t     *field2_buffers = qd_compose_buffers(field2);

    content->buffers = *field1_buffers;
    DEQ_INIT(*field1_buffers);

    qd_buffer_t *buf = DEQ_HEAD(*field2_buffers);
    while (buf) {
        DEQ_REMOVE_HEAD(*field2_buffers);
        DEQ_INSERT_TAIL(content->buffers, buf);
        buf = DEQ_HEAD(*field2_buffers);
    }
}
Example #17
0
static char* list_well_formed(item_list_t list, char *key)
{
    item_t *ptr;
    item_t *last  = 0;
    int     size  = DEQ_SIZE(list);
    int     count = 0;
    char    str[32];

    ptr = DEQ_HEAD(list);
    while (ptr) {
        str[count] = ptr->letter;
        count++;
        if (DEQ_PREV(ptr) != last) return "Corrupt previous link";
        last = ptr;
        ptr = DEQ_NEXT(ptr);
    }
    str[count] = '\0';
    if (strcmp(str, key) != 0) return "Invalid key";

    if (count != size) return "Size different from number of items (forward)";

    count = 0;
    last  = 0;
    ptr   = DEQ_TAIL(list);
    while (ptr) {
        count++;
        if (DEQ_NEXT(ptr) != last) return "Corrupt next link";
        last = ptr;
        ptr = DEQ_PREV(ptr);
    }

    if (count != size) return "Size different from number of items (backward)";

    return 0;
}
void qdra_config_link_route_get_next_CT(qdr_core_t *core, qdr_query_t *query)
{
    qdr_link_route_t *lr = 0;

    if (query->next_offset < DEQ_SIZE(core->link_routes)) {
        lr = DEQ_HEAD(core->link_routes);
        for (int i = 0; i < query->next_offset && lr; i++)
            lr = DEQ_NEXT(lr);
    }

    if (lr) {
        //
        // Write the columns of the addr entity into the response body.
        //
        qdr_agent_write_config_link_route_CT(query, lr);

        //
        // Advance to the next object
        //
        qdr_manage_advance_config_link_route_CT(query, lr);
    } else
        query->more = false;

    //
    // Enqueue the response.
    //
    qdr_agent_enqueue_response_CT(core, query);
}
Example #19
0
unsigned int qd_buffer_list_clone(qd_buffer_list_t *dst, const qd_buffer_list_t *src)
{
    uint32_t len = 0;
    DEQ_INIT(*dst);
    qd_buffer_t *buf = DEQ_HEAD(*src);
    while (buf) {
        size_t to_copy = qd_buffer_size(buf);
        unsigned char *src = qd_buffer_base(buf);
        len += to_copy;
        while (to_copy) {
            qd_buffer_t *newbuf = qd_buffer();
            size_t count = qd_buffer_capacity(newbuf);
            // default buffer capacity may have changed,
            // so don't assume it will fit:
            if (count > to_copy) count = to_copy;
            memcpy(qd_buffer_cursor(newbuf), src, count);
            qd_buffer_insert(newbuf, count);
            DEQ_INSERT_TAIL(*dst, newbuf);
            src += count;
            to_copy -= count;
        }
        buf = DEQ_NEXT(buf);
    }
    return len;
}
Example #20
0
void qdra_link_get_next_CT(qdr_core_t *core, qdr_query_t *query)
{
    qdr_link_t *link = 0;

        if (query->next_offset < DEQ_SIZE(core->open_links)) {
            link = DEQ_HEAD(core->open_links);
            for (int i = 0; i < query->next_offset && link; i++)
                link = DEQ_NEXT(link);
        }

    if (link) {
        //
        // Write the columns of the link entity into the response body.
        //
        qdr_agent_write_link_CT(query, link);

        //
        // Advance to the next link
        //
        qdr_manage_advance_link_CT(query, link);
    } else
        query->more = false;

    //
    // Enqueue the response.
    //
    qdr_agent_enqueue_response_CT(core, query);
}
Example #21
0
static int get_failover_info_length(qd_failover_item_list_t   conn_info_list)
{
    int arr_length = 0;
    qd_failover_item_t *item = DEQ_HEAD(conn_info_list);

    item = DEQ_NEXT(item);
    while(item) {
        if (item->scheme) {
            // The +3 is for the '://'
            arr_length += strlen(item->scheme) + 3;
        }
        if (item->host_port) {
            arr_length += strlen(item->host_port);
        }
        item = DEQ_NEXT(item);
        if (item) {
            // This is for the comma between the items
            arr_length += 2;
        }
    }

    if (arr_length > 0)
        // This is for the final '\0'
        arr_length += 1;

    return arr_length;
}
void qdra_config_auto_link_get_next_CT(qdr_core_t *core, qdr_query_t *query)
{
    qdr_auto_link_t *al = 0;

    if (query->next_offset < DEQ_SIZE(core->auto_links)) {
        al = DEQ_HEAD(core->auto_links);
        for (int i = 0; i < query->next_offset && al; i++)
            al = DEQ_NEXT(al);
    }

    if (al) {
        //
        // Write the columns of the addr entity into the response body.
        //
        qdr_agent_write_config_auto_link_CT(query, al);

        //
        // Advance to the next object
        //
        qdr_manage_advance_config_auto_link_CT(query, al);
    } else
        query->more = false;

    //
    // Enqueue the response.
    //
    qdr_agent_enqueue_response_CT(core, query);
}
Example #23
0
void qdr_route_del_auto_link_CT(qdr_core_t *core, qdr_auto_link_t *al)
{
    //
    // Disassociate from the connection identifier.  Check to see if the identifier
    // should be removed.
    //
    qdr_conn_identifier_t *cid = al->conn_id;
    if (cid) {
        qdr_connection_ref_t * cref = DEQ_HEAD(cid->connection_refs);
        while (cref) {
            qdr_auto_link_deactivate_CT(core, al, cref->conn);
            cref = DEQ_NEXT(cref);
        }
        DEQ_REMOVE_N(REF, cid->auto_link_refs, al);
        qdr_route_check_id_for_deletion_CT(core, cid);
    }

    //
    // Disassociate the auto link from its address.  Check to see if the address
    // should be removed.
    //
    qdr_address_t *addr = al->addr;
    if (addr && --addr->ref_count == 0)
        qdr_check_addr_CT(core, addr, false);

    //
    // Remove the auto link from the core list.
    //
    DEQ_REMOVE(core->auto_links, al);
    free(al->name);
    free(al->external_addr);
    free_qdr_auto_link_t(al);
}
Example #24
0
static hash_item_t *hash_internal_insert(hash_t *h, nx_field_iterator_t *key, int *error)
{
    unsigned long  idx  = hash_function(key) & h->bucket_mask;
    hash_item_t   *item = DEQ_HEAD(h->buckets[idx].items);

    *error = 0;

    while (item) {
        if (nx_field_iterator_equal(key, item->key))
            break;
        item = item->next;
    }

    if (item) {
        *error = -1;
        return 0;
    }

    item = new_hash_item_t();
    if (!item) {
        *error = -2;
        return 0;
    }

    DEQ_ITEM_INIT(item);
    item->key = nx_field_iterator_copy(key);

    DEQ_INSERT_TAIL(h->buckets[idx].items, item);
    h->size++;
    return item;
}
Example #25
0
void qd_log_impl(qd_log_source_t *source, qd_log_level_t level, const char *file, int line, const char *fmt, ...)
{
    if (!qd_log_enabled(source, level)) return;

    qd_log_entry_t *entry = new_qd_log_entry_t();
    DEQ_ITEM_INIT(entry);
    entry->module = source->module;
    entry->level  = level;
    entry->file   = file ? strdup(file) : 0;
    entry->line   = line;
    time(&entry->time);
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(entry->text, TEXT_MAX, fmt, ap);
    va_end(ap);

    write_log(source, entry);

    // Bounded buffer of log entries, keep most recent.
    sys_mutex_lock(log_lock);
    DEQ_INSERT_TAIL(entries, entry);
    if (DEQ_SIZE(entries) > LIST_MAX)
        qd_log_entry_free_lh(DEQ_HEAD(entries));
    sys_mutex_unlock(log_lock);
}
void *router_core_thread(void *arg)
{
    qdr_core_t        *core = (qdr_core_t*) arg;
    qdr_action_list_t  action_list;
    qdr_action_t      *action;

    qdr_forwarder_setup_CT(core);
    qdr_route_table_setup_CT(core);
    qdr_agent_setup_CT(core);

    qd_log(core->log, QD_LOG_INFO, "Router Core thread running. %s/%s", core->router_area, core->router_id);
    while (core->running) {
        //
        // Use the lock only to protect the condition variable and the action list
        //
        sys_mutex_lock(core->action_lock);

        //
        // Block on the condition variable when there is no action to do
        //
        while (core->running && DEQ_IS_EMPTY(core->action_list))
            sys_cond_wait(core->action_cond, core->action_lock);

        //
        // Move the entire action list to a private list so we can process it without
        // holding the lock
        //
        DEQ_MOVE(core->action_list, action_list);
        sys_mutex_unlock(core->action_lock);

        //
        // Process and free all of the action items in the list
        //
        action = DEQ_HEAD(action_list);
        while (action) {
            DEQ_REMOVE_HEAD(action_list);
            if (action->label)
                qd_log(core->log, QD_LOG_TRACE, "Core action '%s'%s", action->label, core->running ? "" : " (discard)");
            action->action_handler(core, action, !core->running);
            free_qdr_action_t(action);
            action = DEQ_HEAD(action_list);
        }
    }

    qd_log(core->log, QD_LOG_INFO, "Router Core thread exited");
    return 0;
}
void qd_connection_manager_start(qd_dispatch_t *qd)
{
    qd_config_listener_t  *cl = DEQ_HEAD(qd->connection_manager->config_listeners);
    qd_config_connector_t *cc = DEQ_HEAD(qd->connection_manager->config_connectors);

    while (cl) {
        if (cl->listener == 0)
            cl->listener = qd_server_listen(qd, &cl->configuration, cl);
        cl = DEQ_NEXT(cl);
    }

    while (cc) {
        if (cc->connector == 0)
            cc->connector = qd_server_connect(qd, &cc->configuration, cc);
        cc = DEQ_NEXT(cc);
    }
}
Example #28
0
/// Caller must hold log_source_lock
static qd_log_source_t* lookup_log_source_lh(const char *module)
{
    if (strcasecmp(module, SOURCE_DEFAULT) == 0)
        return default_log_source;
    qd_log_source_t *src = DEQ_HEAD(source_list);
    DEQ_FIND(src, strcasecmp(module, src->module) == 0);
    return src;
}
Example #29
0
// Get events in the add/remove cache into a python list of (action, type, pointer)
// Locks the entity cache so entities can be updated safely (prevent entities from being deleted.)
// Do not processs any entities if return error code != 0
// Must call qd_entity_refresh_end when done, regardless of error code.
qd_error_t qd_entity_refresh_begin(PyObject *list) {
    if (!event_lock) return QD_ERROR_NONE;    /* Unit tests don't call qd_entity_cache_initialize */
    qd_error_clear();
    sys_mutex_lock(event_lock);
    entity_event_t *event = DEQ_HEAD(event_list);
    while (event) {
        PyObject *tuple = Py_BuildValue("(isl)", (int)event->action, event->type, (long)event->object);
        if (!tuple) { qd_error_py(); break; }
        int err = PyList_Append(list, tuple);
        Py_DECREF(tuple);
        if (err) { qd_error_py(); break; }
        DEQ_REMOVE_HEAD(event_list);
        free(event);
        event = DEQ_HEAD(event_list);
    }
    return qd_error_code();
}
Example #30
0
static void release_buffer_chain(qd_buffer_list_t *chain)
{
    while (DEQ_SIZE(*chain)) {
        qd_buffer_t *buf = DEQ_HEAD(*chain);
        DEQ_REMOVE_HEAD(*chain);
        qd_buffer_free(buf);
    }
}