/** * Frees memory taken by a r_public aor structure * @param p - the r_public to be deallocated */ void free_r_public(r_public *p) { r_contact *c,*n; r_subscriber *s,*m; if (!p) return; if (p->aor.s) shm_free(p->aor.s); if (p->early_ims_ip.s) shm_free(p->early_ims_ip.s); if (p->s) { lock_get(p->s->lock); p->s->ref_count--; if (p->s->ref_count<=0) { free_user_data(p->s); }else lock_release(p->s->lock); } c = p->head; while(c){ n = c->next; free_r_contact(c); c = n; } s = p->shead; while(s){ m = s->next; free_r_subscriber(s); s = m; } shm_free(p); }
/** * Updates the r_public with the new reg_state and ims_subscription values. * If not found, it will be inserted. * \note Aquires the lock on the hash_slot on success, so release it when you are done. * @param aor - the address of record * @param reg_state - new registration state, NULL if no update necessary * @param s - the new subscription attached, NULL if no update necessary * @returns the update r_public or NULL on error */ r_public* update_r_public(str aor,enum Reg_States *reg_state,ims_subscription **s) { r_public *p; p = get_r_public(aor); if (!p){ if (reg_state && *reg_state && *reg_state!=NOT_REGISTERED && s) return add_r_public(aor,*reg_state,*s); else return 0; }else{ if (reg_state) p->reg_state = *reg_state; if (*s) { if (p->s){ lock_get(p->s->lock); if (p->s->ref_count==1){ free_user_data(p->s); }else{ p->s->ref_count--; lock_release(p->s->lock); } } p->s = *s; lock_get(p->s->lock); p->s->ref_count++; lock_release(p->s->lock); } return p; } }
/** * Deletes a dialog from the hash table * \note Must be called with a lock on the dialogs slot * @param d - the dialog to delete */ void del_user_data(user_d *d) { LOG(L_INFO,"DBG:"M_NAME":del_user_data(): Deleting user data for uri %.*s and service %.*s\n", d->user_uri.len,d->user_uri.s, d->service.len,d->service.s); if (d->prev) d->prev->next = d->next; else user_datas[d->hash].head = d->next; if (d->next) d->next->prev = d->prev; else user_datas[d->hash].tail = d->prev; free_user_data(d); }
/** * Destroy the hash table */ void destroy_lrf_user_data(){ int i; user_d *d,*nd; for(i=0;i<user_data_hash_size;i++){ lrf_lock(i); d = user_datas[i].head; while(d){ nd = d->next; free_user_data(d); d = nd; } lrf_unlock(i); lock_dealloc(user_datas[i].lock); } shm_free(user_datas); user_datas = NULL; }
/** * Updates the r_public with the new reg_state and ims_subscription values, with a previous lock on the registrar. * If not found, it will be inserted. * \note Aquires the lock on the hash_slot on success and if the lock is different from previous_lock, so release it * when you are done and if different then from previous lock. * @param aor - the address of record * @param locked_hash - the previous lock on the registrar * @param reg_state - new registration state, NULL if no update necessary * @param s - the new subscription attached, NULL if no update necessary * @returns the update r_public or NULL on error */ r_public* update_r_public_previous_lock(str aor,int locked_hash,enum Reg_States *reg_state,ims_subscription **s, str *ccf1, str *ccf2, str *ecf1, str *ecf2) { r_public *p=0; p = get_r_public_previous_lock(aor,locked_hash); if (!p){ if (reg_state && *reg_state && *reg_state!=NOT_REGISTERED && s){ p = add_r_public_previous_lock(aor,locked_hash,*reg_state,*s); if (!p) return p; if (ccf1) { if (p->ccf1.s) shm_free(p->ccf1.s); STR_SHM_DUP( &(p->ccf1), ccf1,"SHM CCF1"); } if (ccf2) { if (p->ccf2.s) shm_free(p->ccf2.s); STR_SHM_DUP( &(p->ccf2), ccf2,"SHM CCF2"); } if (ecf1) { if (p->ecf1.s) shm_free(p->ecf1.s); STR_SHM_DUP( &(p->ecf1), ecf1,"SHM ECF1"); } if (ecf2) { if (p->ecf2.s) shm_free(p->ecf2.s); STR_SHM_DUP( &(p->ecf2), ecf2,"SHM ECF2"); } return p; } else return 0; }else{ if (reg_state) p->reg_state = *reg_state; if (*s) { if (p->s){ lock_get(p->s->lock); if (p->s->ref_count==1){ free_user_data(p->s); }else{ p->s->ref_count--; lock_release(p->s->lock); } } p->s = *s; lock_get(p->s->lock); p->s->ref_count++; lock_release(p->s->lock); } if (ccf1) { if (p->ccf1.s) shm_free(p->ccf1.s); STR_SHM_DUP( &(p->ccf1), ccf1,"SHM CCF1"); } if (ccf2) { if (p->ccf2.s) shm_free(p->ccf2.s); STR_SHM_DUP( &(p->ccf2), ccf2,"SHM CCF2"); } if (ecf1) { if (p->ecf1.s) shm_free(p->ecf1.s); STR_SHM_DUP( &(p->ecf1), ecf1,"SHM ECF1"); } if (ecf2) { if (p->ecf2.s) shm_free(p->ecf2.s); STR_SHM_DUP( &(p->ecf2), ecf2,"SHM ECF2"); } return p; } out_of_memory: return p; }
/** * Updates the r_public with the new reg_state and ims_subscription values. * If not found, it will be inserted. * \note Aquires the lock on the hash_slot on success, so release it when you are done. * @param aor - the address of record * @param reg_state - new registration state, NULL if no update necessary * @param s - the new subscription attached, NULL if no update necessary * @returns the update r_public or NULL on error */ r_public* update_r_public(str aor,enum Reg_States *reg_state,ims_subscription **s, str *ccf1, str *ccf2, str *ecf1, str *ecf2) { r_public *p=0; //LOG(L_CRIT,"update_r_public():with aor %.*s\n",aor.len,aor.s); if ((*s)->wpsi) { p = get_r_public_wpsi(aor); } else { p = get_r_public(aor); } if (!p){ //LOG(L_DBG,"updating a new r_public profile\n"); if (reg_state && *reg_state && *reg_state!=NOT_REGISTERED && s){ p = add_r_public(aor,*reg_state,*s); if (!p) return p; if (ccf1) { if (p->ccf1.s) shm_free(p->ccf1.s); STR_SHM_DUP( &(p->ccf1), ccf1,"SHM CCF1"); } if (ccf2) { if (p->ccf2.s) shm_free(p->ccf2.s); STR_SHM_DUP( &(p->ccf2), ccf2,"SHM CCF2"); } if (ecf1) { if (p->ecf1.s) shm_free(p->ecf1.s); STR_SHM_DUP( &(p->ecf1), ecf1,"SHM ECF1"); } if (ecf2) { if (p->ecf2.s) shm_free(p->ecf2.s); STR_SHM_DUP( &(p->ecf2), ecf2,"SHM ECF2"); } //LOG(L_DBG,"update_r_public(): it was actually adding\n"); return p; } else return 0; }else{ //LOG(L_DBG,"updating a not so new r_public profile\n"); if (reg_state) p->reg_state = *reg_state; if (*s) { if (p->s){ lock_get(p->s->lock); if (p->s->ref_count==1){ free_user_data(p->s); }else{ p->s->ref_count--; lock_release(p->s->lock); } } p->s = *s; lock_get(p->s->lock); p->s->ref_count++; lock_release(p->s->lock); if ((*s)->wpsi) { p->s=NULL; if (p->prev) p->prev->next=p->next; else registrar[r_hash_size].head=p->next; if (p->next) p->next->prev=p->prev; else registrar[r_hash_size].tail=p->prev; free_r_public(p); r_unlock(r_hash_size); p=add_r_public(aor,0,*s); } } if (ccf1) { if (p->ccf1.s) shm_free(p->ccf1.s); STR_SHM_DUP( &(p->ccf1), ccf1,"SHM CCF1"); } if (ccf2) { if (p->ccf2.s) shm_free(p->ccf2.s); STR_SHM_DUP( &(p->ccf2), ccf2,"SHM CCF2"); } if (ecf1) { if (p->ecf1.s) shm_free(p->ecf1.s); STR_SHM_DUP( &(p->ecf1), ecf1,"SHM ECF1"); } if (ecf2) { if (p->ecf2.s) shm_free(p->ecf2.s); STR_SHM_DUP( &(p->ecf2), ecf2,"SHM ECF2"); } //LOG(L_DBG,"update_r_public(): return normaly\n"); return p; } out_of_memory: return p; }