Exemplo n.º 1
0
void add_subscription(ims_subscription* s) {
    int sl;
    sl = core_hash(&s->private_identity, 0, subs_hash_size);
    lock_subscription_slot(sl);
    add_subscription_unsafe(s);
    unlock_subscription_slot(sl);
}
Exemplo n.º 2
0
/**
 * @brief Get a subscription from the subscription list based on the IMPI
 *  NB - does not return with a lock on the subscription but does increment ref count
 * @param impu string of impu to search for
 * @param s ims_subscription to be returned if found
 * @param leave_slot_locked if no subscription is found return with the slot locked (in case we want to add) 
 * @return 0 on success
 */
int get_subscription(str* impi_s, ims_subscription** s, int leave_slot_locked) {
    int subscription_hash, sl;
    ims_subscription* ptr;

    subscription_hash = core_hash(impi_s, 0, 0);
    sl = subscription_hash & (subs_hash_size - 1);
    lock_subscription_slot(sl);
    ptr = ims_subscription_list->slot[sl].first;
    while (ptr) {
        if ((impi_s->len == ptr->private_identity.len) && (memcmp(impi_s->s, ptr->private_identity.s, impi_s->len) == 0)) {
            LM_DBG("found an existing subscription for IMPI [%.*s]\n", impi_s->len, impi_s->s);
            (*s) = ptr;
            lock_subscription(ptr);
            ref_subscription_unsafe(ptr);
            unlock_subscription(ptr);
            unlock_subscription_slot(sl);
            return 0;
        }
        ptr = ptr->next;
    }
    if (!leave_slot_locked)
        unlock_subscription_slot(sl);
    return 1;
}
Exemplo n.º 3
0
/*!
 * \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;
    
}
Exemplo n.º 4
0
/*!
 * \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);
        }
    }
    
}