/** @internal Remove dialog usage. * * Zap dialog state (leg, tag and route) if no usages remain. */ static void nua_dialog_usage_remove_at(nua_owner_t *own, nua_dialog_state_t *ds, nua_dialog_usage_t **at, nua_client_request_t *cr0, nua_server_request_t *sr0) { if (*at) { nua_dialog_usage_t *du = *at; sip_event_t const *o = NULL; nua_client_request_t *cr, *cr_next; nua_server_request_t *sr, *sr_next; *at = du->du_next; o = du->du_event; SU_DEBUG_5(("nua(%p): removing %s usage%s%s\n", (void *)own, nua_dialog_usage_name(du), o ? " with event " : "", o ? o->o_type :"")); du->du_class->usage_remove(own, ds, du, cr0, sr0); /* Clean reference to saved client request */ if (du->du_cr) nua_client_bind(du->du_cr, NULL); /* Clean references from queued client requests */ for (cr = ds->ds_cr; cr; cr = cr_next) { cr_next = cr->cr_next; if (cr->cr_usage == du) cr->cr_usage = NULL; } /* Clean references from queued server requests */ for (sr = ds->ds_sr; sr; sr = sr_next) { sr_next = sr->sr_next; if (sr->sr_usage == du) { sr->sr_usage = NULL; if (sr != sr0) nua_server_request_destroy(sr); } } su_home_unref(own); su_free(own, du); } /* Zap dialog if there are no more usages */ if (ds->ds_terminating) ; else if (ds->ds_usage == NULL) { nua_dialog_remove(own, ds, NULL); ds->ds_has_events = 0; return; } else { nua_dialog_log_usage(own, ds); } }
void nh_destroy(nua_t *nua, nua_handle_t *nh) { assert(nh); assert(nh != nua->nua_dhandle); if (nh->nh_notifier) nea_server_destroy(nh->nh_notifier), nh->nh_notifier = NULL; while (nh->nh_ds->ds_cr) nua_client_request_complete(nh->nh_ds->ds_cr); while (nh->nh_ds->ds_sr) nua_server_request_destroy(nh->nh_ds->ds_sr); nua_dialog_deinit(nh, nh->nh_ds); if (nh_is_inserted(nh)) nh_remove(nua, nh); nua_handle_unref(nh); /* Remove stack reference */ }