static inline void free_dlg_dlg(struct dlg_cell *dlg) { struct dlg_val *dv; unsigned int i; if (dlg->cbs.first) destroy_dlg_callbacks_list(dlg->cbs.first); if (dlg->profile_links) destroy_linkers(dlg->profile_links); if (dlg->legs) { for( i=0 ; i<dlg->legs_no[DLG_LEGS_USED] ; i++) { shm_free(dlg->legs[i].tag.s); shm_free(dlg->legs[i].r_cseq.s); if (dlg->legs[i].contact.s) shm_free(dlg->legs[i].contact.s); /* + route_set */ } shm_free(dlg->legs); } while (dlg->vals) { dv = dlg->vals; dlg->vals = dlg->vals->next; shm_free(dv); } shm_free(dlg); }
void destroy_dlg_callbacks(unsigned int types) { if (types&DLGCB_CREATED) { if (create_cbs && create_cbs!=POINTER_CLOSED_MARKER) { destroy_dlg_callbacks_list(create_cbs->first); shm_free(create_cbs); } create_cbs = POINTER_CLOSED_MARKER; } if (types&DLGCB_LOADED) { if (load_cbs && load_cbs!=POINTER_CLOSED_MARKER) { destroy_dlg_callbacks_list(load_cbs->first); shm_free(load_cbs); } load_cbs = POINTER_CLOSED_MARKER; } }
/*! * \brief Destroy a dialog, run callbacks and free memory * \param dlg destroyed dialog */ void destroy_dlg(struct dlg_cell *dlg) { int ret = 0; struct dlg_var *var; LM_DBG("destroying dialog %p (ref %d)\n", dlg, dlg->ref); ret = remove_dialog_timer(&dlg->tl); if (ret < 0) { LM_CRIT("unable to unlink the timer on dlg %p [%u:%u] " "with clid '%.*s' and tags '%.*s' '%.*s'\n", dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, dlg->callid.s, dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s, dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s); } else if (ret > 0) { LM_DBG("removed timer for dlg %p [%u:%u] " "with clid '%.*s' and tags '%.*s' '%.*s'\n", dlg, dlg->h_entry, dlg->h_id, dlg->callid.len, dlg->callid.s, dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s, dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s); } run_dlg_callbacks( DLGCB_DESTROY , dlg, NULL, NULL, DLG_DIR_NONE, 0); /* delete the dialog from DB*/ if (dlg_db_mode) remove_dialog_from_db(dlg); if (dlg->cbs.first) destroy_dlg_callbacks_list(dlg->cbs.first); if (dlg->profile_links) destroy_linkers(dlg->profile_links); if (dlg->tag[DLG_CALLER_LEG].s) shm_free(dlg->tag[DLG_CALLER_LEG].s); if (dlg->tag[DLG_CALLEE_LEG].s) shm_free(dlg->tag[DLG_CALLEE_LEG].s); if (dlg->cseq[DLG_CALLER_LEG].s) shm_free(dlg->cseq[DLG_CALLER_LEG].s); if (dlg->cseq[DLG_CALLEE_LEG].s) shm_free(dlg->cseq[DLG_CALLEE_LEG].s); if (dlg->toroute_name.s) shm_free(dlg->toroute_name.s); while (dlg->vars) { var = dlg->vars; dlg->vars = dlg->vars->next; shm_free(var->key.s); shm_free(var->value.s); shm_free(var); } shm_free(dlg); dlg = 0; }
int register_dlgcb(struct dlg_cell *dlg, int types, dialog_cb f, void *param, param_free_cb ff ) { struct dlg_callback *cb; if ( types&DLGCB_LOADED ) { if (types!=DLGCB_LOADED) { LM_CRIT("DLGCB_LOADED type must be register alone!\n"); return -1; } } else if ( types&DLGCB_CREATED ) { if (types!=DLGCB_CREATED) { LM_CRIT("DLGCB_CREATED type must be register alone!\n"); return -1; } } else { if (dlg==0) { LM_CRIT("non-DLGCB_CREATED type " "must be register to a dialog (dlg missing)!\n"); return -1; } } cb = (struct dlg_callback*)shm_malloc(sizeof(struct dlg_callback)); if (cb==0) { LM_ERR("no more shm mem\n"); return -1; } cb->types = types; cb->callback = f; cb->param = param; cb->callback_param_free = ff; if ( types==DLGCB_CREATED ) { if (load_cbs==POINTER_CLOSED_MARKER) { LM_CRIT("DLGCB_CREATED type registered after shutdown!?!\n"); goto error; } if (create_cbs==0) { /* not initialized yet */ if ( (create_cbs=init_dlg_callback())==NULL ) { LM_ERR("no more shm mem\n"); goto error; } } cb->next = create_cbs->first; create_cbs->first = cb; create_cbs->types |= types; } else if (types==DLGCB_LOADED) { if (load_cbs==POINTER_CLOSED_MARKER) { /* run the callback on the spot */ run_load_callback(cb); destroy_dlg_callbacks_list(cb); return 0; } if (load_cbs==0) { /* not initialized yet */ if ( (load_cbs=init_dlg_callback())==NULL ) { LM_ERR("no more shm mem\n"); goto error; } } cb->next = load_cbs->first; load_cbs->first = cb; load_cbs->types |= types; } else { cb->next = dlg->cbs.first; dlg->cbs.first = cb; dlg->cbs.types |= types; } return 0; error: shm_free(cb); return -1; }