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); } }
void qdr_core_unbind_address_conn_CT(qdr_core_t *core, qdr_address_t *addr, qdr_connection_t *conn) { qdr_del_connection_ref(&addr->conns, conn); if (DEQ_IS_EMPTY(addr->conns)) { const char *key = (const char*) qd_hash_key_by_handle(addr->hash_handle); qdr_post_mobile_removed_CT(core, key); qdrc_event_addr_raise(core, QDRC_EVENT_ADDR_NO_LONGER_LOCAL_DEST, addr); } }
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); }
static void qdr_link_route_deactivate_CT(qdr_core_t *core, qdr_link_route_t *lr, qdr_connection_t *conn) { const char *key; qdr_route_log_CT(core, "Link Route Deactivated", lr->name, lr->identity, conn); // // Deactivate the address(es) for link-routed destinations. // if (lr->addr) { qdr_del_connection_ref(&lr->addr->conns, conn); if (DEQ_IS_EMPTY(lr->addr->conns)) { key = (const char*) qd_hash_key_by_handle(lr->addr->hash_handle); if (key) qdr_post_mobile_removed_CT(core, key); } } }
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); }