/*! * \brief Run timer handler for given domain * \param _d domain */ void mem_timer_udomain(udomain_t* _d) { struct impurecord* ptr, *t; struct ucontact* contact_ptr; int i, n, temp; //go through contacts first n = contact_list->max_collisions; LM_DBG("*** mem_timer_udomain - checking contacts - START ***\n"); for (i = 0; i < contact_list->size; i++) { lock_contact_slot_i(i); contact_ptr = contact_list->slot[i].first; while (contact_ptr) { LM_DBG("We have a contact in the new contact list in slot %d = [%.*s] (%.*s) which expires in %lf seconds and has a ref count of %d\n", i, contact_ptr->aor.len, contact_ptr->aor.s, contact_ptr->c.len, contact_ptr->c.s, (double) contact_ptr->expires - time(NULL), contact_ptr->ref_count); //contacts are now deleted during impurecord processing contact_ptr = contact_ptr->next; } if (contact_list->slot[i].n > n) { n = contact_list->slot[i].n; } unlock_contact_slot_i(i); contact_list->max_collisions = n; } LM_DBG("*** mem_timer_udomain - checking contacts - FINISHED ***\n"); temp = 0; n = _d->max_collisions; LM_DBG("*** mem_timer_udomain - checking IMPUs - START ***\n"); for (i = 0; i < _d->size; i++) { lock_ulslot(_d, i); ptr = _d->table[i].first; temp = 0; while (ptr) { temp = 1; #ifdef EXTRA_DEBUG LM_DBG("ULSLOT %d LOCKED\n", i); #endif t = ptr; ptr = ptr->next; timer_impurecord(t); } if (temp) { #ifdef EXTRA_DEBUG LM_DBG("ULSLOT %d UN-LOCKED\n", i); #endif } if (_d->table[i].n > n) n = _d->table[i].n; unlock_ulslot(_d, i); _d->max_collisions = n; } LM_DBG("*** mem_timer_udomain - checking IMPUs - FINISHED ***\n"); n = ims_subscription_list->max_collisions; for (i = 0; i < ims_subscription_list->size; i++) { lock_subscription_slot(i); if (ims_subscription_list->slot[i].n > n) { n = ims_subscription_list->slot[i].n; } unlock_subscription_slot(i); } ims_subscription_list->max_collisions = n; }
/*! * \brief Run timer handler for given domain * \param _d domain */ void mem_timer_udomain(udomain_t* _d) { struct impurecord* ptr, *t; struct ucontact* contact_ptr, *tmp_contact_ptr; int i; //go through contacts first LM_DBG("*** mem_timer_udomain - checking contacts - START ***\n"); for (i = 0; i < contact_list->size; i++) { #ifdef EXTRA_DEBUG LM_DBG("looking for contacts in slot %d\n", i); #endif lock_contact_slot_i(i); contact_ptr = contact_list->slot[i].first; while (contact_ptr) { LM_DBG("We have a contact in the new contact list in slot %d = [%.*s] (%.*s) which expires in %lf seconds and has a ref count of %d\n", i, contact_ptr->aor.len, contact_ptr->aor.s, contact_ptr->c.len, contact_ptr->c.s, (double) contact_ptr->expires - time(NULL), contact_ptr->ref_count); if (contact_ptr->ref_count <= 0) { LM_DBG("Deleting contact [%.*s]\n", contact_ptr->c.len, contact_ptr->c.s); tmp_contact_ptr = contact_ptr->next; delete_ucontact(contact_ptr); contact_ptr = tmp_contact_ptr; } else { contact_ptr = contact_ptr->next; } } unlock_contact_slot_i(i); } LM_DBG("*** mem_timer_udomain - checking contacts - FINISHED ***\n"); int temp = 0; LM_DBG("*** mem_timer_udomain - checking IMPUs - START ***\n"); for (i = 0; i < _d->size; i++) { lock_ulslot(_d, i); ptr = _d->table[i].first; temp = 0; while (ptr) { temp = 1; #ifdef EXTRA_DEBUG LM_DBG("ULSLOT %d LOCKED\n", i); #endif t = ptr; ptr = ptr->next; timer_impurecord(t); // if (t->reg_state == IMPU_NOT_REGISTERED && t->shead == 0) { // //remove it - housekeeping - not sure why its still here...? // if (exists_ulcb_type(t->cbs, UL_IMPU_NR_DELETE)) // run_ul_callbacks(t->cbs, UL_IMPU_NR_DELETE, t, NULL); // // LM_DBG("about to delete impurecord\n"); // delete_impurecord(_d, &t->public_identity, t); // } //else if (t->reg_state == IMPU_UNREGISTERED) {//Remove IMPU record if it is in state IMPU_UNREGISTERED and has expired // // if (time_now >= t->expires) {//check here and only remove if no subscribes - if there is a subscribe then bump the validity by unreg_validity // if(t->shead != 0){ // LM_DBG("This impurecord still has subscriptions - extending the expiry"); // t->expires = time(NULL) + unreg_validity; // } else { // if (exists_ulcb_type(t->cbs, UL_IMPU_UNREG_EXPIRED)) // run_ul_callbacks(t->cbs, UL_IMPU_UNREG_EXPIRED, t, NULL); // LM_DBG("about to delete impurecord\n"); // delete_impurecord(_d, &t->public_identity, t); // } // } // //} else if (t->reg_state != IMPU_UNREGISTERED && t->contacts == 0) { /* Remove the entire record if it is empty IFF it is not an UNREGISTERED RECORD */ // } else if (t->reg_state != IMPU_UNREGISTERED && t->num_contacts == 0 && t->shead == 0) { /* Remove the entire record if it is empty IFF it is not an UNREGISTERED RECORD */ // /* TS 23.228 5.3.2.1 (release 11) */ // //need a way of distinguishing between deletes that need a SAR (expired) and deletes that do not need a SAR (explicit de reg) // //we only want to send one SAR for each implicit IMPU set // //make sure all IMPU's associated with this set are de-registered before calling the callbacks // int first=1; // int this_is_first = 0; // // lock_get(t->s->lock); // for (k = 0; k < t->s->service_profiles_cnt; k++){ // for (j = 0;j < t->s->service_profiles[k].public_identities_cnt;j++) { // impu = &(t->s->service_profiles[k].public_identities[j]); // // sl = core_hash(&impu->public_identity, 0, _d->size); // if (sl != i) // lock_udomain(_d, &impu->public_identity); // // if (first) { // first = 0; //dont do anything - we will leave this impu to be processed as normal // if (!strncmp(impu->public_identity.s, t->public_identity.s, t->public_identity.len)) { // //we are the first in the implicit set // this_is_first = 1; // } // } else { // //set all other implicits to not registered // if (update_impurecord(_d, &impu->public_identity, IMPU_NOT_REGISTERED, // -1/*barring*/, -1 /*do not change send sar on delete */, 0/*is_primary*/, NULL, NULL, NULL, NULL, NULL, &temp_impu) != 0) { // LM_ERR("Unable to update impurecord for <%.*s>\n", impu->public_identity.len, impu->public_identity.s); // } // } // if (sl != i) // unlock_udomain(_d, &impu->public_identity); // } // } // lock_release(t->s->lock); // // if (this_is_first) { // //now run a normal callback on our // if (exists_ulcb_type(t->cbs, UL_IMPU_REG_NC_DELETE)) // run_ul_callbacks(t->cbs, UL_IMPU_REG_NC_DELETE, t, NULL); // LM_DBG("about to delete impurecord\n"); // delete_impurecord(_d, &t->public_identity, t); // } // } } if (temp) { #ifdef EXTRA_DEBUG LM_DBG("ULSLOT %d UN-LOCKED\n", i); #endif } unlock_ulslot(_d, i); } LM_DBG("*** mem_timer_udomain - checking IMPUs - FINISHED ***\n"); }
/*! * \brief Run timer handler for given domain * \param _d domain */ void mem_timer_udomain(udomain_t* _d, int istart, int istep) { struct impurecord* ptr, *t; struct ucontact* contact_ptr; unsigned int num_expired_contacts = 0; int i, n, temp; time_t now; int abort = 0; int slot; int ref_count_db; now = time(0); if (istart == 0) { int numcontacts = contact_list->size*2; //assume we should be ok for each slot to have 2 collisions if (expired_contacts_size < numcontacts) { LM_DBG("Changing expired_contacts list size from %d to %d\n", expired_contacts_size, numcontacts); if (expired_contacts){ pkg_free(expired_contacts); } expired_contacts = (ucontact_t**)pkg_malloc(numcontacts*sizeof(ucontact_t**)); if (!expired_contacts) { LM_ERR("no more pkg mem trying to allocate [%lu] bytes\n", numcontacts*sizeof(ucontact_t**)); return; } expired_contacts_size = numcontacts; } //go through contacts first n = contact_list->max_collisions; LM_DBG("*** mem_timer_udomain - checking contacts - START ***\n"); for (i=0; i < contact_list->size; i++) { lock_contact_slot_i(i); contact_ptr = contact_list->slot[i].first; while (contact_ptr) { if (num_expired_contacts >= numcontacts) { LM_WARN("we don't have enough space to expire all contacts in this pass - will continue in next pass\n"); abort = 1; break; } LM_DBG("We have a [3gpp=%d] contact in the new contact list in slot %d = [%.*s] (%.*s) which expires in %lf seconds and has a ref count of %d (state: %s)\n", contact_ptr->is_3gpp, i, contact_ptr->aor.len, contact_ptr->aor.s, contact_ptr->c.len, contact_ptr->c.s, (double) contact_ptr->expires - now, contact_ptr->ref_count, get_contact_state_as_string(contact_ptr->state)); //contacts are now deleted during impurecord processing if ((contact_ptr->expires-now) <= 0) { if (contact_ptr->state == CONTACT_DELAYED_DELETE) { if (contact_ptr->ref_count <= 0) { LM_DBG("contact in state CONTACT_DELATED_DELETE is about to be deleted"); expired_contacts[num_expired_contacts] = contact_ptr; num_expired_contacts++; } else { /* we could fall here not because contact is still referenced but also because we failed before to get a lock to unref the contact, so we check if contact is really referenced*/ if (db_mode != NO_DB) { LM_DBG("contact in state CONTACT_DELAYED_DELETE still has a ref count of [%d] in memory. Check on DB \n", contact_ptr->ref_count); ref_count_db = db_check_if_contact_is_linked(contact_ptr); if (ref_count_db < 0) { LM_ERR("Unable to check if contact is unlinked\n"); } else if (ref_count_db == 0) { LM_DBG("Contact has ref count [%d] but there's no link on the DB. Deleting contact", contact_ptr->ref_count); contact_ptr->ref_count = 0; expired_contacts[num_expired_contacts] = contact_ptr; num_expired_contacts++; } else { LM_DBG("Contact in state CONTACT_DELAYED_DELETE has ref count [%d] on DB", ref_count_db); } } else { LM_DBG("contact in state CONTACT_DELAYED_DELETE still has a ref count of [%d] in memory. Not doing anything for now \n", contact_ptr->ref_count); } } } else if (contact_ptr->state != CONTACT_DELETED) { LM_DBG("expiring contact [%.*s].... setting to CONTACT_EXPIRE_PENDING_NOTIFY\n", contact_ptr->aor.len, contact_ptr->aor.s); contact_ptr->state = CONTACT_EXPIRE_PENDING_NOTIFY; ref_contact_unsafe(contact_ptr); expired_contacts[num_expired_contacts] = contact_ptr; num_expired_contacts++; } } contact_ptr = contact_ptr->next; } if (contact_list->slot[i].n > n) { n = contact_list->slot[i].n; } unlock_contact_slot_i(i); contact_list->max_collisions = n; if (abort == 1) { break; } } LM_DBG("*** mem_timer_udomain - checking contacts - FINISHED ***\n"); } temp = 0; n = _d->max_collisions; LM_DBG("*** mem_timer_udomain - checking IMPUs - START ***\n"); for (i = istart; i < _d->size; i+=istep) { lock_ulslot(_d, i); ptr = _d->table[i].first; temp = 0; while (ptr) { temp = 1; #ifdef EXTRA_DEBUG LM_DBG("ULSLOT %d LOCKED\n", i); #endif t = ptr; ptr = ptr->next; timer_impurecord(t); } if (temp) { #ifdef EXTRA_DEBUG LM_DBG("ULSLOT %d UN-LOCKED\n", i); #endif } if (_d->table[i].n > n) n = _d->table[i].n; unlock_ulslot(_d, i); _d->max_collisions = n; } LM_DBG("*** mem_timer_udomain - checking IMPUs - FINISHED ***\n"); if (istart == 0) { n = ims_subscription_list->max_collisions; for (i = 0; i < ims_subscription_list->size; i++) { lock_subscription_slot(i); if (ims_subscription_list->slot[i].n > n) { n = ims_subscription_list->slot[i].n; } unlock_subscription_slot(i); } ims_subscription_list->max_collisions = n; /* now we delete the expired contacts. (mark them for deletion */ for (i=0; i<num_expired_contacts; i++) { slot = expired_contacts[i]->sl; lock_contact_slot_i(slot); if (expired_contacts[i]->state != CONTACT_DELAYED_DELETE) { LM_DBG("Setting contact state to CONTACT_DELETED for contact [%.*s]\n", expired_contacts[i]->aor.len, expired_contacts[i]->aor.s); expired_contacts[i]->state = CONTACT_DELETED; unref_contact_unsafe(expired_contacts[i]); } else { LM_DBG("deleting contact [%.*s]\n", expired_contacts[i]->aor.len, expired_contacts[i]->aor.s); delete_scontact(expired_contacts[i]); } unlock_contact_slot_i(slot); } } }