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); } }
void qd_connection_manager_free(qd_connection_manager_t *cm) { if (!cm) return; qd_config_listener_t *cl = DEQ_HEAD(cm->config_listeners); while (cl) { DEQ_REMOVE_HEAD(cm->config_listeners); qd_server_config_free(&cl->configuration); qd_config_listener_free(cm, cl); cl = DEQ_HEAD(cm->config_listeners); } qd_config_connector_t *cc = DEQ_HEAD(cm->config_connectors); while (cc) { DEQ_REMOVE_HEAD(cm->config_connectors); qd_server_config_free(&cc->configuration); qd_config_connector_free(cm, cc); cc = DEQ_HEAD(cm->config_connectors); } qd_config_ssl_profile_t *sslp = DEQ_HEAD(cm->config_ssl_profiles); while (sslp) { qd_config_ssl_profile_free(cm, sslp); sslp = DEQ_HEAD(cm->config_ssl_profiles); } sys_mutex_free(cm->ssl_profile_lock); }
void qd_connection_manager_free(qd_connection_manager_t *cm) { if (!cm) return; qd_config_listener_t *cl = DEQ_HEAD(cm->config_listeners); while (cl) { DEQ_REMOVE_HEAD(cm->config_listeners); qd_server_listener_free(cl->listener); qd_server_config_free(&cl->configuration); free(cl); cl = DEQ_HEAD(cm->config_listeners); } qd_config_connector_t *cc = DEQ_HEAD(cm->config_connectors); while(cc) { DEQ_REMOVE_HEAD(cm->config_connectors); qd_server_connector_free(cc->connector); qd_server_config_free(&cc->configuration); free(cc); cc = DEQ_HEAD(cm->config_connectors); } qd_config_connector_t *odc = DEQ_HEAD(cm->on_demand_connectors); while(odc) { DEQ_REMOVE_HEAD(cm->on_demand_connectors); if (odc->connector) qd_server_connector_free(odc->connector); qd_server_config_free(&odc->configuration); free(odc); odc = DEQ_HEAD(cm->on_demand_connectors); } }
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); }
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); }
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); } }
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); } }
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); } }
static int fire_head() { sys_mutex_lock(lock); int result = DEQ_SIZE(pending_timers); nx_timer_t *timer = DEQ_HEAD(pending_timers); if (timer) { DEQ_REMOVE_HEAD(pending_timers); nx_timer_idle_LH(timer); fire_mask |= (unsigned long) timer->context; } sys_mutex_unlock(lock); return result; }
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); } }
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; }
// 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(); }
static void qdr_general_handler(void *context) { qdr_core_t *core = (qdr_core_t*) context; qdr_general_work_list_t work_list; qdr_general_work_t *work; sys_mutex_lock(core->work_lock); DEQ_MOVE(core->work_list, work_list); sys_mutex_unlock(core->work_lock); work = DEQ_HEAD(work_list); while (work) { DEQ_REMOVE_HEAD(work_list); work->handler(core, work); free_qdr_general_work_t(work); work = DEQ_HEAD(work_list); } }
void qd_hash_free(qd_hash_t *h) { if (!h) return; qd_hash_item_t *item; int idx; for (idx = 0; idx < h->bucket_count; idx++) { item = DEQ_HEAD(h->buckets[idx].items); while (item) { free(item->key); DEQ_REMOVE_HEAD(h->buckets[idx].items); free_qd_hash_item_t(item); item = DEQ_HEAD(h->buckets[idx].items); } } free(h->buckets); free(h); }
void work_queue_put(work_queue_t *w, pn_connector_t *conn) { work_item_t *item; if (!w) return; if (DEQ_SIZE(w->free_list) == 0) allocate_batch(w); if (DEQ_SIZE(w->free_list) == 0) return; item = DEQ_HEAD(w->free_list); DEQ_REMOVE_HEAD(w->free_list); item->conn = conn; DEQ_INSERT_TAIL(w->items, item); }
pn_connector_t *work_queue_get(work_queue_t *w) { work_item_t *item; pn_connector_t *conn; if (!w) return 0; item = DEQ_HEAD(w->items); if (!item) return 0; DEQ_REMOVE_HEAD(w->items); conn = item->conn; item->conn = 0; DEQ_INSERT_TAIL(w->free_list, item); return conn; }
static void qdr_agent_response_handler(void *context) { qdr_core_t *core = (qdr_core_t*) context; qdr_query_t *query; bool done = false; while (!done) { sys_mutex_lock(core->query_lock); query = DEQ_HEAD(core->outgoing_query_list); if (query) DEQ_REMOVE_HEAD(core->outgoing_query_list); done = DEQ_SIZE(core->outgoing_query_list) == 0; sys_mutex_unlock(core->query_lock); if (query) { bool more = query->more; core->agent_response_handler(query->context, &query->status, more); if (!more) qdr_query_free(query); } } }
void qd_parse_free(qd_parsed_field_t *field) { if (!field) return; assert(field->parent == 0); if (field->raw_iter) qd_iterator_free(field->raw_iter); if (field->typed_iter) qd_iterator_free(field->typed_iter); qd_parsed_field_t *sub_field = DEQ_HEAD(field->children); while (sub_field) { qd_parsed_field_t *next = DEQ_NEXT(sub_field); DEQ_REMOVE_HEAD(field->children); sub_field->parent = 0; qd_parse_free(sub_field); sub_field = next; } free_qd_parsed_field_t(field); }
void qd_container_free(qd_container_t *container) { if (!container) return; if (container->default_node) qd_container_destroy_node(container->default_node); qd_node_t *node = DEQ_HEAD(container->nodes); while (node) { qd_container_destroy_node(node); node = DEQ_HEAD(container->nodes); } qdc_node_type_t *nt = DEQ_HEAD(container->node_type_list); while (nt) { DEQ_REMOVE_HEAD(container->node_type_list); free(nt); nt = DEQ_HEAD(container->node_type_list); } qd_hash_free(container->node_map); qd_hash_free(container->node_type_map); sys_mutex_free(container->lock); free(container); }
/** * Outbound Delivery Handler */ static void router_tx_handler(void* context, dx_link_t *link, pn_delivery_t *delivery) { dx_router_t *router = (dx_router_t*) context; pn_link_t *pn_link = pn_delivery_link(delivery); dx_router_link_t *rlink = (dx_router_link_t*) dx_link_get_context(link); dx_message_t *msg; size_t size; sys_mutex_lock(router->lock); msg = DEQ_HEAD(rlink->out_fifo); if (!msg) { // TODO - Recind the delivery sys_mutex_unlock(router->lock); return; } DEQ_REMOVE_HEAD(rlink->out_fifo); size = (DEQ_SIZE(rlink->out_fifo)); sys_mutex_unlock(router->lock); dx_message_send(msg, pn_link); // // If there is no incoming delivery, it was pre-settled. In this case, // we must pre-settle the outgoing delivery as well. // if (dx_message_in_delivery(msg)) { pn_delivery_set_context(delivery, (void*) msg); dx_message_set_out_delivery(msg, delivery); } else { pn_delivery_settle(delivery); dx_free_message(msg); } pn_link_advance(pn_link); pn_link_offered(pn_link, size); }
void *dx_alloc(dx_alloc_type_desc_t *desc, dx_alloc_pool_t **tpool) { int idx; // // If the descriptor is not initialized, set it up now. // if (!desc->global_pool) dx_alloc_init(desc); // // 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; // // Fast case: If there's an item on the local free list, take it off the // list and return it. Since everything we've touched is thread-local, // there is no need to acquire a lock. // item_t *item = DEQ_HEAD(pool->free_list); if (item) { DEQ_REMOVE_HEAD(pool->free_list); return &item[1]; } // // The local free list is empty, we need to either rebalance a batch // of items from the global list or go to the heap to get new memory. // sys_mutex_lock(desc->lock); if (DEQ_SIZE(desc->global_pool->free_list) >= desc->config->transfer_batch_size) { // // Rebalance a full batch from the global free list to the thread list. // desc->stats->batches_rebalanced_to_threads++; desc->stats->held_by_threads += desc->config->transfer_batch_size; for (idx = 0; idx < desc->config->transfer_batch_size; idx++) { item = DEQ_HEAD(desc->global_pool->free_list); DEQ_REMOVE_HEAD(desc->global_pool->free_list); DEQ_INSERT_TAIL(pool->free_list, item); } } else { // // Allocate a full batch from the heap and put it on the thread list. // for (idx = 0; idx < desc->config->transfer_batch_size; idx++) { item = (item_t*) malloc(sizeof(item_t) + desc->total_size); if (item == 0) break; DEQ_ITEM_INIT(item); item->desc = desc; DEQ_INSERT_TAIL(pool->free_list, item); desc->stats->held_by_threads++; desc->stats->total_alloc_from_heap++; } } sys_mutex_unlock(desc->lock); item = DEQ_HEAD(pool->free_list); if (item) { DEQ_REMOVE_HEAD(pool->free_list); return &item[1]; } return 0; }
static void qd_log_source_free_lh(qd_log_source_t* src) { DEQ_REMOVE_HEAD(source_list); log_sink_free_lh(src->sink); free(src->module); free(src); }
static char* test_deq_basic(void *context) { item_list_t list; item_t item[10]; item_t *ptr; int idx; char *subtest; DEQ_INIT(list); if (DEQ_SIZE(list) != 0) return "Expected zero initial size"; for (idx = 0; idx < 10; idx++) { DEQ_ITEM_INIT(&item[idx]); item[idx].letter = 'A' + idx; DEQ_INSERT_TAIL(list, &item[idx]); } if (DEQ_SIZE(list) != 10) return "Expected 10 items in list"; ptr = DEQ_HEAD(list); if (!ptr) return "Expected valid head item"; if (DEQ_PREV(ptr)) return "Head item has non-null previous link"; if (ptr->letter != 'A') return "Expected item A at the head"; if (DEQ_NEXT(ptr) == 0) return "Head item has null next link"; subtest = list_well_formed(list, "ABCDEFGHIJ"); if (subtest) return subtest; DEQ_REMOVE_HEAD(list); if (DEQ_SIZE(list) != 9) return "Expected 9 items in list"; ptr = DEQ_HEAD(list); if (ptr->letter != 'B') return "Expected item B at the head"; subtest = list_well_formed(list, "BCDEFGHIJ"); if (subtest) return subtest; DEQ_REMOVE_TAIL(list); if (DEQ_SIZE(list) != 8) return "Expected 8 items in list"; ptr = DEQ_TAIL(list); if (ptr->letter != 'I') return "Expected item I at the tail"; subtest = list_well_formed(list, "BCDEFGHI"); if (subtest) return subtest; DEQ_REMOVE(list, &item[4]); if (DEQ_SIZE(list) != 7) return "Expected 7 items in list"; subtest = list_well_formed(list, "BCDFGHI"); if (subtest) return subtest; DEQ_REMOVE(list, &item[1]); if (DEQ_SIZE(list) != 6) return "Expected 6 items in list"; subtest = list_well_formed(list, "CDFGHI"); if (subtest) return subtest; DEQ_REMOVE(list, &item[8]); if (DEQ_SIZE(list) != 5) return "Expected 5 items in list"; subtest = list_well_formed(list, "CDFGH"); if (subtest) return subtest; DEQ_INSERT_HEAD(list, &item[8]); if (DEQ_SIZE(list) != 6) return "Expected 6 items in list"; ptr = DEQ_HEAD(list); if (ptr->letter != 'I') return "Expected item I at the head"; subtest = list_well_formed(list, "ICDFGH"); if (subtest) return subtest; DEQ_INSERT_AFTER(list, &item[4], &item[7]); if (DEQ_SIZE(list) != 7) return "Expected 7 items in list"; ptr = DEQ_TAIL(list); if (ptr->letter != 'E') return "Expected item E at the head"; subtest = list_well_formed(list, "ICDFGHE"); if (subtest) return subtest; DEQ_INSERT_AFTER(list, &item[1], &item[5]); if (DEQ_SIZE(list) != 8) return "Expected 8 items in list"; subtest = list_well_formed(list, "ICDFBGHE"); if (subtest) return subtest; if (item[0].prev || item[0].next) return "Unlisted item A has non-null pointers"; if (item[9].prev || item[9].next) return "Unlisted item J has non-null pointers"; return 0; }
const char *qd_parse_annotations_v1( bool strip_anno_in, qd_iterator_t *ma_iter_in, qd_parsed_field_t **ma_ingress, qd_parsed_field_t **ma_phase, qd_parsed_field_t **ma_to_override, qd_parsed_field_t **ma_trace, qd_iterator_pointer_t *blob_pointer, uint32_t *blob_item_count) { // Do full parse qd_iterator_reset(ma_iter_in); qd_parsed_turbo_list_t annos; uint32_t user_entries; uint32_t user_bytes; const char * parse_error = qd_parse_turbo(ma_iter_in, &annos, &user_entries, &user_bytes); if (parse_error) { return parse_error; } qd_parsed_turbo_t *anno; if (!strip_anno_in) { anno = DEQ_HEAD(annos); while (anno) { qd_iterator_t *key_iter = qd_iterator_buffer(anno->bufptr.buffer, anno->bufptr.cursor - qd_buffer_base(anno->bufptr.buffer), anno->size, ITER_VIEW_ALL); assert(key_iter); qd_parsed_field_t *key_field = qd_parse(key_iter); assert(key_field); qd_iterator_t *iter = qd_parse_raw(key_field); assert(iter); qd_parsed_turbo_t *anno_val = DEQ_NEXT(anno); assert(anno_val); qd_iterator_t *val_iter = qd_iterator_buffer(anno_val->bufptr.buffer, anno_val->bufptr.cursor - qd_buffer_base(anno_val->bufptr.buffer), anno_val->size, ITER_VIEW_ALL); assert(val_iter); qd_parsed_field_t *val_field = qd_parse(val_iter); assert(val_field); // Hoist the key name out of the buffers into a normal char array char key_name[QD_MA_MAX_KEY_LEN + 1]; (void)qd_iterator_strncpy(iter, key_name, QD_MA_MAX_KEY_LEN + 1); // transfer ownership of the extracted value to the message if (!strcmp(key_name, QD_MA_TRACE)) { *ma_trace = val_field; } else if (!strcmp(key_name, QD_MA_INGRESS)) { *ma_ingress = val_field; } else if (!strcmp(key_name, QD_MA_TO)) { *ma_to_override = val_field; } else if (!strcmp(key_name, QD_MA_PHASE)) { *ma_phase = val_field; } else { // TODO: this key had the QD_MA_PREFIX but it does not match // one of the actual fields. qd_parse_free(val_field); } qd_iterator_free(key_iter); qd_parse_free(key_field); qd_iterator_free(val_iter); // val_field is usually handed over to message_private and is freed anno = DEQ_NEXT(anno_val); } } anno = DEQ_HEAD(annos); while (anno) { DEQ_REMOVE_HEAD(annos); free_qd_parsed_turbo_t(anno); anno = DEQ_HEAD(annos); } // Adjust size of user annotation blob by the size of the router // annotations blob_pointer->remaining = user_bytes; assert(blob_pointer->remaining >= 0); *blob_item_count = user_entries; assert(*blob_item_count >= 0); return 0; }
const char *qd_parse_turbo(qd_iterator_t *iter, qd_parsed_turbo_list_t *annos, uint32_t *user_entries, uint32_t *user_bytes) { if (!iter || !annos || !user_entries || !user_bytes) return "missing argument"; DEQ_INIT(*annos); *user_entries = 0; *user_bytes = 0; // The iter is addressing the message-annotations map. // Open the field describing the map's items uint8_t tag = 0; uint32_t size = 0; uint32_t count = 0; uint32_t length_of_count = 0; uint32_t length_of_size = 0; const char * parse_error = get_type_info(iter, &tag, &size, &count, &length_of_size, &length_of_count); if (parse_error) return parse_error; if (count == 0) return 0; int n_allocs = 0; // Do skeletal parse of each map element for (uint32_t idx = 0; idx < count; idx++) { qd_parsed_turbo_t *turbo; if (n_allocs < QD_MA_FILTER_LEN * 2) { turbo = new_qd_parsed_turbo_t(); n_allocs++; } else { // Retire an existing element. // If there are this many in the list then this one cannot be a // router annotation and must be a user annotation. turbo = DEQ_HEAD(*annos); *user_entries += 1; *user_bytes += sizeof(turbo->tag) + turbo->size + turbo->length_of_size; DEQ_REMOVE_HEAD(*annos); } if (!turbo) return "failed to allocate qd_parsed_turbo_t"; ZERO(turbo); // Get the buffer pointers for the map element qd_iterator_get_view_cursor(iter, &turbo->bufptr); // Get description of the map element parse_error = get_type_info(iter, &turbo->tag, &turbo->size, &turbo->count, &turbo->length_of_size, &turbo->length_of_count); if (parse_error) { return parse_error; } // Save parsed element DEQ_INSERT_TAIL(*annos, turbo); // Advance map iterator to next map element qd_iterator_advance(iter, turbo->size - turbo->length_of_count); } // remove leading annos in the queue if their prefix is not a match and // return them as part of the user annotations for (int idx=0; idx < n_allocs; idx += 2) { qd_parsed_turbo_t *turbo = DEQ_HEAD(*annos); assert(turbo); if (qd_iterator_prefix_ptr(&turbo->bufptr, turbo->length_of_size + 1, QD_MA_PREFIX)) break; // leading anno is a user annotation map key // remove the key and value from the list and accumulate them as user items *user_bytes += sizeof(turbo->tag) + turbo->size + turbo->length_of_size; DEQ_REMOVE_HEAD(*annos); free_qd_parsed_turbo_t(turbo); turbo = DEQ_HEAD(*annos); assert(turbo); *user_bytes += sizeof(turbo->tag) + turbo->size + turbo->length_of_size; DEQ_REMOVE_HEAD(*annos); free_qd_parsed_turbo_t(turbo); *user_entries += 2; } return parse_error; }
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); // Drain the general work lists qdr_general_handler(core); // // 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_link_route_t *link_route = 0; while ( (link_route = DEQ_HEAD(core->link_routes))) { DEQ_REMOVE_HEAD(core->link_routes); qdr_core_delete_link_route(core, link_route); } qdr_auto_link_t *auto_link = 0; while ( (auto_link = DEQ_HEAD(core->auto_links))) { DEQ_REMOVE_HEAD(core->auto_links); qdr_core_delete_auto_link(core, auto_link); } qdr_exchange_free_all(core); 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_parse_tree_free(core->addr_parse_tree); qd_parse_tree_free(core->link_route_tree[QD_INCOMING]); qd_parse_tree_free(core->link_route_tree[QD_OUTGOING]); qdr_node_t *rnode = 0; while ( (rnode = DEQ_HEAD(core->routers)) ) { qdr_router_node_free(core, rnode); } qdr_link_t *link = DEQ_HEAD(core->open_links); while (link) { DEQ_REMOVE_HEAD(core->open_links); if (link->core_endpoint) qdrc_endpoint_do_cleanup_CT(core, link->core_endpoint); qdr_del_link_ref(&link->conn->links, link, QDR_LINK_LIST_CLASS_CONNECTION); qdr_del_link_ref(&link->conn->links_with_work[link->priority], link, QDR_LINK_LIST_CLASS_WORK); free(link->name); free(link->disambiguated_name); free(link->terminus_addr); free(link->ingress_histogram); free(link->insert_prefix); free(link->strip_prefix); link->name = 0; free_qdr_link_t(link); link = DEQ_HEAD(core->open_links); } qdr_connection_t *conn = DEQ_HEAD(core->open_connections); while (conn) { DEQ_REMOVE_HEAD(core->open_connections); if (conn->conn_id) { qdr_del_connection_ref(&conn->conn_id->connection_refs, conn); qdr_route_check_id_for_deletion_CT(core, conn->conn_id); } qdr_connection_work_t *work = DEQ_HEAD(conn->work_list); while (work) { DEQ_REMOVE_HEAD(conn->work_list); qdr_connection_work_free_CT(work); work = DEQ_HEAD(conn->work_list); } qdr_connection_free(conn); conn = DEQ_HEAD(core->open_connections); } // at this point all the conn identifiers have been freed qd_hash_free(core->conn_id_hash); qdr_modules_finalize(core); 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); }
static char *test_tracemask(void *context) { qd_bitmask_t *bm = NULL; qd_tracemask_t *tm = qd_tracemask(); qd_buffer_list_t list; static char error[1024]; error[0] = 0; qd_iterator_set_address(false, "0", "ROUTER"); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.A", 0); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.B", 1); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.C", 2); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.D", 3); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.E", 4); qd_tracemask_add_router(tm, "amqp:/_topo/0/Router.F", 5); qd_tracemask_set_link(tm, 0, 4); qd_tracemask_set_link(tm, 3, 10); qd_tracemask_set_link(tm, 4, 3); qd_tracemask_set_link(tm, 5, 2); qd_composed_field_t *comp = qd_compose_subfield(0); qd_compose_start_list(comp); qd_compose_insert_string(comp, "0/Router.A"); qd_compose_insert_string(comp, "0/Router.D"); qd_compose_insert_string(comp, "0/Router.E"); qd_compose_end_list(comp); DEQ_INIT(list); qd_compose_take_buffers(comp, &list); qd_compose_free(comp); int length = 0; qd_buffer_t *buf = DEQ_HEAD(list); while (buf) { length += qd_buffer_size(buf); buf = DEQ_NEXT(buf); } qd_iterator_t *iter = qd_iterator_buffer(DEQ_HEAD(list), 0, length, ITER_VIEW_ALL); qd_parsed_field_t *pf = qd_parse(iter); qd_iterator_free(iter); int ingress = -1; bm = qd_tracemask_create(tm, pf, &ingress); if (qd_bitmask_cardinality(bm) != 3) { sprintf(error, "Expected cardinality of 3, got %d", qd_bitmask_cardinality(bm)); goto cleanup; } if (ingress != 0) { sprintf(error, "(A) Expected ingress index of 0, got %d", ingress); goto cleanup; } int total = 0; int bit, c; for (QD_BITMASK_EACH(bm, bit, c)) { total += bit; } if (total != 17) { sprintf(error, "Expected total bit value of 17, got %d", total); goto cleanup; } qd_bitmask_free(bm); bm = 0; qd_tracemask_del_router(tm, 3); qd_tracemask_remove_link(tm, 0); ingress = -1; bm = qd_tracemask_create(tm, pf, &ingress); qd_parse_free(pf); pf = 0; if (qd_bitmask_cardinality(bm) != 1) { sprintf(error, "Expected cardinality of 1, got %d", qd_bitmask_cardinality(bm)); goto cleanup; } if (ingress != 0) { sprintf(error, "(B) Expected ingress index of 0, got %d", ingress); goto cleanup; } total = 0; for (QD_BITMASK_EACH(bm, bit, c)) { total += bit; } if (total != 3) { sprintf(error, "Expected total bit value of 3, got %d", total); // fallthrough } cleanup: qd_parse_free(pf); qd_tracemask_free(tm); qd_bitmask_free(bm); for (qd_buffer_t *buf = DEQ_HEAD(list); buf; buf = DEQ_HEAD(list)) { DEQ_REMOVE_HEAD(list); qd_buffer_free(buf); } return *error ? error : 0; }