void sca_hash_table_free( sca_hash_table *ht ) { sca_hash_entry *e, *e_tmp; unsigned int i; if ( ht == NULL ) { return; } for ( i = 0; i < ht->size; i++ ) { if ( ht->slots[ i ].entries == NULL ) { continue; } sca_hash_table_lock_index( ht, i ); for ( e = ht->slots[ i ].entries; e != NULL; e = e_tmp ) { e_tmp = e->next; e->free_entry( e->value ); shm_free( e ); } sca_hash_table_unlock_index( ht, i ); lock_destroy( &ht->slots[ i ].lock ); lock_dealloc( &ht->slots[ i ].lock ); } shm_free( ht->slots ); shm_free( ht ); }
/* * send a call-info NOTIFY to all subscribers to a given SCA AoR. */ int sca_notify_call_info_subscribers(sca_mod *scam, str *subscription_aor) { sca_hash_slot *slot; sca_hash_entry *e; sca_subscription *sub; str headers = STR_NULL; str hash_key = STR_NULL; char hdrbuf[SCA_HEADERS_MAX_LEN]; char keybuf[512]; char *event_name; int slot_idx; int rc = -1; assert(scam->subscriptions != NULL); assert(!SCA_STR_EMPTY(subscription_aor)); LM_DBG("Notifying ALL subscribers of AOR %.*s due to a SUBSCRIBTION request\n", STR_FMT(subscription_aor)); event_name = sca_event_name_from_type(SCA_EVENT_TYPE_CALL_INFO); if (subscription_aor->len + strlen(event_name) >= sizeof(keybuf)) { LM_ERR("Hash key %.*s + %s is too long\n", STR_FMT(subscription_aor), event_name); return (-1); } hash_key.s = keybuf; SCA_STR_COPY(&hash_key, subscription_aor); SCA_STR_APPEND_CSTR(&hash_key, event_name); slot_idx = sca_hash_table_index_for_key(scam->subscriptions, &hash_key); slot = sca_hash_table_slot_for_index(scam->subscriptions, slot_idx); sca_hash_table_lock_index(scam->subscriptions, slot_idx); for (e = slot->entries; e != NULL; e = e->next) { sub = (sca_subscription *) e->value; if (!SCA_STR_EQ(subscription_aor, &sub->target_aor)) { continue; } if (headers.len == 0) { headers.s = hdrbuf; if (sca_notify_build_headers_from_info(&headers, sizeof(hdrbuf), scam, sub, SCA_CALL_INFO_APPEARANCE_INDEX_ANY) < 0) { LM_ERR("Failed to build NOTIFY headers\n"); goto done; } } // XXX would like this to be wrapped in one location sub->dialog.notify_cseq += 1; if (sca_notify_subscriber_internal(scam, sub, &headers) < 0) { goto done; } } rc = 1; done: sca_hash_table_unlock_index(scam->subscriptions, slot_idx); return (rc); }