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_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); }
void qdr_route_del_link_route_CT(qdr_core_t *core, qdr_link_route_t *lr) { // // Disassociate from the connection identifier. Check to see if the identifier // should be removed. // qdr_conn_identifier_t *cid = lr->conn_id; if (cid) { if (!!cid->open_connection) qdr_link_route_deactivate_CT(core, lr, cid->open_connection); DEQ_REMOVE_N(REF, cid->link_route_refs, lr); qdr_route_check_id_for_deletion_CT(core, cid); } // // Disassociate the link route from its address. Check to see if the address // should be removed. // qdr_address_t *addr = lr->addr; if (addr && --addr->ref_count == 0) qdr_check_addr_CT(core, addr, false); // // Remove the link route from the core list. // DEQ_REMOVE(core->link_routes, lr); free(lr->name); free_qdr_link_route_t(lr); }
void qdr_core_delete_auto_link(qdr_core_t *core, qdr_auto_link_t *al) { if (al->conn_id) { DEQ_REMOVE_N(REF, al->conn_id->auto_link_refs, al); qdr_route_check_id_for_deletion_CT(core, al->conn_id); } qdr_address_t *addr = al->addr; if (addr && --addr->ref_count == 0) qdr_check_addr_CT(core, addr); free(al->name); free(al->external_addr); qdr_core_timer_free_CT(core, al->retry_timer); free_qdr_auto_link_t(al); }
void qdr_core_delete_link_route(qdr_core_t *core, qdr_link_route_t *lr) { if (lr->conn_id) { DEQ_REMOVE_N(REF, lr->conn_id->link_route_refs, lr); qdr_route_check_id_for_deletion_CT(core, lr->conn_id); } if (lr->addr) { if (--lr->addr->ref_count == 0) { qdr_check_addr_CT(core, lr->addr); } } free(lr->add_prefix); free(lr->del_prefix); free(lr->name); free(lr->pattern); free_qdr_link_route_t(lr); }
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); }