From 71f73672b9afcb53f5240e8fd49f726a4a105948 Mon Sep 17 00:00:00 2001 From: jaybeepee Date: Tue, 8 Mar 2016 11:00:01 +0200 Subject: [PATCH] modules/ims_usrloc_scscf: multiprocess local timer support added --- modules/ims_usrloc_scscf/dlist.c | 4 +- modules/ims_usrloc_scscf/dlist.h | 2 +- modules/ims_usrloc_scscf/udomain.c | 157 +++++++++++++++-------------- modules/ims_usrloc_scscf/udomain.h | 2 +- modules/ims_usrloc_scscf/ul_mod.c | 39 ++++++- 5 files changed, 121 insertions(+), 83 deletions(-) diff --git a/modules/ims_usrloc_scscf/dlist.c b/modules/ims_usrloc_scscf/dlist.c index f78a8d057d6..4ecc6786cb0 100644 --- a/modules/ims_usrloc_scscf/dlist.c +++ b/modules/ims_usrloc_scscf/dlist.c @@ -388,7 +388,7 @@ void print_all_udomains(FILE* _f) * \brief Run timer handler of all domains * \return 0 if all timer return 0, != 0 otherwise */ -int synchronize_all_udomains(void) +int synchronize_all_udomains(int istart, int istep) { int res = 0; dlist_t* ptr; @@ -396,7 +396,7 @@ int synchronize_all_udomains(void) get_act_time(); /* Get and save actual time */ for( ptr=root ; ptr ; ptr=ptr->next) - mem_timer_udomain(ptr->d); + mem_timer_udomain(ptr->d, istart, istep); return res; } diff --git a/modules/ims_usrloc_scscf/dlist.h b/modules/ims_usrloc_scscf/dlist.h index e1007006291..28c2f2c24db 100644 --- a/modules/ims_usrloc_scscf/dlist.h +++ b/modules/ims_usrloc_scscf/dlist.h @@ -95,7 +95,7 @@ void print_all_udomains(FILE* _f); * \brief Run timer handler of all domains * \return 0 if all timer return 0, != 0 otherwise */ -int synchronize_all_udomains(void); +int synchronize_all_udomains(int istart, int istep); /*! diff --git a/modules/ims_usrloc_scscf/udomain.c b/modules/ims_usrloc_scscf/udomain.c index 5ef9ecc2e97..cab889bb452 100644 --- a/modules/ims_usrloc_scscf/udomain.c +++ b/modules/ims_usrloc_scscf/udomain.c @@ -259,82 +259,85 @@ ucontact_t** expired_contacts = 0; * \brief Run timer handler for given domain * \param _d domain */ -void mem_timer_udomain(udomain_t* _d) { +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, j; + int i, n, temp; time_t now; int abort = 0; int slot; now = time(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 [%d] 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,j=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; + 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; } - 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: %d)\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, - 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_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: %d)\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, + 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 { + LM_DBG("contact in state CONTACT_DELATED_DELETE still has a ref count of [%d]... 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++; - } else { - LM_DBG("contact in state CONTACT_DELATED_DELETE still has a ref count of [%d]... 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; } - 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"); } - 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++) { + for (i = istart; i < _d->size; i+=istep) { lock_ulslot(_d, i); ptr = _d->table[i].first; temp = 0; @@ -360,29 +363,31 @@ void mem_timer_udomain(udomain_t* _d) { } 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; + 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); } - unlock_subscription_slot(i); - } - ims_subscription_list->max_collisions = n; - - /* now we delete the expired contacts. (mark them for deletion */ - for (i=0; isl; - 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]); + ims_subscription_list->max_collisions = n; + + /* now we delete the expired contacts. (mark them for deletion */ + for (i=0; isl; + 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); } - unlock_contact_slot_i(slot); } } diff --git a/modules/ims_usrloc_scscf/udomain.h b/modules/ims_usrloc_scscf/udomain.h index d47ff0a2bb9..5dc31d35b89 100644 --- a/modules/ims_usrloc_scscf/udomain.h +++ b/modules/ims_usrloc_scscf/udomain.h @@ -113,7 +113,7 @@ void print_udomain(FILE* _f, udomain_t* _d); * \brief Run timer handler for given domain * \param _d domain */ -void mem_timer_udomain(udomain_t* _d); +void mem_timer_udomain(udomain_t* _d, int istart, int istep); int mem_insert_impurecord(struct udomain* _d, str* public_identity, str* private_identity, int reg_state, int barring, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r); diff --git a/modules/ims_usrloc_scscf/ul_mod.c b/modules/ims_usrloc_scscf/ul_mod.c index 35cc307b40d..8d77de0b709 100644 --- a/modules/ims_usrloc_scscf/ul_mod.c +++ b/modules/ims_usrloc_scscf/ul_mod.c @@ -66,6 +66,7 @@ #include "../../modules/ims_dialog/dlg_load.h" #include "../../modules/ims_dialog/dlg_hash.h" #include "ul_scscf_stats.h" +#include "../../timer_proc.h" /* register_sync_timer */ MODULE_VERSION @@ -77,6 +78,7 @@ static int mod_init(void); /*!< Module initialization f static void destroy(void); /*!< Module destroy function */ static void timer(unsigned int ticks, void* param); /*!< Timer handler */ static int child_init(int rank); /*!< Per-child init function */ +static void ul_local_timer(unsigned int ticks, void* param); /*!< Local timer handler */ extern int bind_usrloc(usrloc_api_t* api); extern void contact_dlg_create_handler(struct dlg_cell* dlg, int cb_types, struct dlg_cb_params *dlg_params);/*V1.1*/ @@ -101,6 +103,7 @@ int ul_fetch_rows = 2000; /*!< number of rows to fetch from result */ int ul_hash_size = 9; int subs_hash_size = 9; /*! 0) + register_timer(timer, 0, timer_interval); + } + else + register_sync_timers(ul_timer_procs); + - /* Register cache timer */ - register_timer(timer, 0, timer_interval); /* init the callbacks list */ if (init_ulcb_list() < 0) { @@ -399,6 +411,17 @@ static int mod_init(void) { static int child_init(int rank) { dlist_t* ptr; + int i; + + if (rank == PROC_MAIN && ul_timer_procs > 0) { + for (i = 0; i < ul_timer_procs; i++) { + if (fork_sync_timer(PROC_TIMER, "IMS S-CSCF USRLOC Timer", 1 /*socks flag*/, + ul_local_timer, (void*) (long) i, timer_interval /*sec*/) < 0) { + LM_ERR("failed to start timer routine as process\n"); + return -1; /* error */ + } + } + } /* connecting to DB ? */ switch (db_mode) { @@ -471,8 +494,18 @@ static void timer(unsigned int ticks, void* param) { } LM_DBG("Syncing cache\n"); - if (synchronize_all_udomains() != 0) { + if (synchronize_all_udomains(0, 1) != 0) { LM_ERR("synchronizing cache failed\n"); } } +/*! \brief + * Local timer handler + */ +static void ul_local_timer(unsigned int ticks, void* param) +{ + if (synchronize_all_udomains((int)(long)param, ul_timer_procs) != 0) { + LM_ERR("synchronizing cache failed\n"); + } +} +