Bläddra i källkod

modules/ims_usrloc_scscf: multiprocess local timer support added

jaybeepee 9 år sedan
förälder
incheckning
71f73672b9

+ 2 - 2
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;
 }

+ 1 - 1
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);
 
 
 /*!

+ 81 - 76
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; 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]);
+        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);
         }
-        unlock_contact_slot_i(slot);
     }
     
 }

+ 1 - 1
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);

+ 36 - 3
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;					/*!<number of ims subscription slots*/
 int contacts_hash_size = 9;
+int ul_timer_procs = 0;
 
 struct contact_list* contact_list;
 struct ims_subscription_list* ims_subscription_list;
@@ -163,6 +166,7 @@ static param_export_t params[] = {
     {"sub_dialog_hash_size",INT_PARAM, &sub_dialog_hash_size},
     {"db_mode",				INT_PARAM, &db_mode},
     {"db_url", 				PARAM_STR, &db_url},
+    {"timer_procs",             INT_PARAM, &ul_timer_procs},
 	{0, 0, 0}
 };
 
@@ -358,9 +362,17 @@ static int mod_init(void) {
 	    LM_ERR("Failed to register counters\n");
 	    return -1;
 	}
+        
+        /* Register cache timer */
+	if(ul_timer_procs<=0)
+	{
+		if (timer_interval > 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");
+	}
+}
+