Module: sip-router
Branch: master
Commit: 99da07de696c1f5368bf74ea82fe7df7f8db61a0
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=99da07de696c1f5368bf74ea82fe7df7f8db61a0

Author: Daniel-Constantin Mierla <[email protected]>
Committer: Daniel-Constantin Mierla <[email protected]>
Date:   Tue Jul 22 13:33:24 2014 +0200

uac: new rpc command - uac.reg_reload

- reload the records from database
- old records are kept for at least 150sec more to be sure no active
  registration process is using them
- therefore reload cannot executed more often than 150sec

---

 modules/uac/uac_reg.c |  164 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 154 insertions(+), 10 deletions(-)

diff --git a/modules/uac/uac_reg.c b/modules/uac/uac_reg.c
index da3fdd0..f1344be 100644
--- a/modules/uac/uac_reg.c
+++ b/modules/uac/uac_reg.c
@@ -50,6 +50,7 @@
 #define UAC_REG_AUTHSENT       (1<<3)
 
 #define MAX_UACH_SIZE 2048
+#define UAC_REG_GC_INTERVAL    150
 
 typedef struct _reg_uac
 {
@@ -88,10 +89,13 @@ typedef struct _reg_entry
 typedef struct _reg_ht
 {
        unsigned int htsize;
+       time_t stime;
        reg_entry_t *entries;
 } reg_ht_t;
 
 static reg_ht_t *_reg_htable = NULL;
+static reg_ht_t *_reg_htable_gc = NULL;
+static gen_lock_t *_reg_htable_gc_lock = NULL;
 
 int reg_use_domain = 0;
 int reg_timer_interval = 90;
@@ -168,10 +172,50 @@ int uac_reg_init_ht(unsigned int sz)
 {
        int i;
 
+       _reg_htable_gc_lock = (gen_lock_t*)shm_malloc(sizeof(gen_lock_t));
+       if(_reg_htable_gc_lock == NULL)
+       {
+               LM_ERR("no more shm for lock\n");
+               return -1;
+       }
+       if(lock_init(_reg_htable_gc_lock)==0)
+       {
+               LM_ERR("cannot init global lock\n");
+               shm_free((void*)_reg_htable_gc_lock);
+               return -1;
+       }
+       _reg_htable_gc = (reg_ht_t*)shm_malloc(sizeof(reg_ht_t));
+       if(_reg_htable_gc==NULL)
+       {
+               LM_ERR("no more shm\n");
+               lock_destroy(_reg_htable_gc_lock);
+               shm_free((void*)_reg_htable_gc_lock);
+               return -1;
+       }
+       memset(_reg_htable_gc, 0, sizeof(reg_ht_t));
+       _reg_htable_gc->htsize = sz;
+
+       _reg_htable_gc->entries =
+                       
(reg_entry_t*)shm_malloc(_reg_htable_gc->htsize*sizeof(reg_entry_t));
+       if(_reg_htable_gc->entries==NULL)
+       {
+               LM_ERR("no more shm.\n");
+               shm_free(_reg_htable_gc);
+               lock_destroy(_reg_htable_gc_lock);
+               shm_free((void*)_reg_htable_gc_lock);
+               return -1;
+       }
+       memset(_reg_htable_gc->entries, 0, 
_reg_htable_gc->htsize*sizeof(reg_entry_t));
+
+
        _reg_htable = (reg_ht_t*)shm_malloc(sizeof(reg_ht_t));
        if(_reg_htable==NULL)
        {
                LM_ERR("no more shm\n");
+               shm_free(_reg_htable_gc->entries);
+               shm_free(_reg_htable_gc);
+               lock_destroy(_reg_htable_gc_lock);
+               shm_free((void*)_reg_htable_gc_lock);
                return -1;
        }
        memset(_reg_htable, 0, sizeof(reg_ht_t));
@@ -182,7 +226,11 @@ int uac_reg_init_ht(unsigned int sz)
        if(_reg_htable->entries==NULL)
        {
                LM_ERR("no more shm.\n");
+               shm_free(_reg_htable_gc->entries);
+               shm_free(_reg_htable_gc);
                shm_free(_reg_htable);
+               lock_destroy(_reg_htable_gc_lock);
+               shm_free((void*)_reg_htable_gc_lock);
                return -1;
        }
        memset(_reg_htable->entries, 0, 
_reg_htable->htsize*sizeof(reg_entry_t));
@@ -199,6 +247,10 @@ int uac_reg_init_ht(unsigned int sz)
                        }
                        shm_free(_reg_htable->entries);
                        shm_free(_reg_htable);
+                       shm_free(_reg_htable_gc->entries);
+                       shm_free(_reg_htable_gc);
+                       lock_destroy(_reg_htable_gc_lock);
+                       shm_free((void*)_reg_htable_gc_lock);
                        return -1;
                }
        }
@@ -215,6 +267,37 @@ int uac_reg_free_ht(void)
        reg_item_t *it = NULL;
        reg_item_t *it0 = NULL;
 
+       if(_reg_htable_gc_lock != NULL)
+       {
+               lock_destroy(_reg_htable_gc_lock);
+               shm_free((void*)_reg_htable_gc_lock);
+               _reg_htable_gc_lock = NULL;
+       }
+       if(_reg_htable_gc!=NULL)
+       {
+               for(i=0; i<_reg_htable_gc->htsize; i++)
+               {
+                       it = _reg_htable_gc->entries[i].byuuid;
+                       while(it)
+                       {
+                               it0 = it;
+                               it = it->next;
+                               shm_free(it0);
+                       }
+                       it = _reg_htable_gc->entries[i].byuser;
+                       while(it)
+                       {
+                               it0 = it;
+                               it = it->next;
+                               shm_free(it0->r);
+                               shm_free(it0);
+                       }
+               }
+               shm_free(_reg_htable_gc->entries);
+               shm_free(_reg_htable_gc);
+               _reg_htable_gc = NULL;
+       }
+
        if(_reg_htable==NULL)
        {
                LM_DBG("no hash table\n");
@@ -250,31 +333,30 @@ int uac_reg_free_ht(void)
 /**
  *
  */
-int uac_reg_reset_ht(void)
+int uac_reg_reset_ht_gc(void)
 {
        int i;
        reg_item_t *it = NULL;
        reg_item_t *it0 = NULL;
 
-       if(_reg_htable==NULL)
+       if(_reg_htable_gc==NULL)
        {
                LM_DBG("no hash table\n");
                return -1;
        }
-       for(i=0; i<_reg_htable->htsize; i++)
+       for(i=0; i<_reg_htable_gc->htsize; i++)
        {
-               lock_get(&_reg_htable->entries[i].lock);
                /* free entries */
-               it = _reg_htable->entries[i].byuuid;
+               it = _reg_htable_gc->entries[i].byuuid;
                while(it)
                {
                        it0 = it;
                        it = it->next;
                        shm_free(it0);
                }
-               _reg_htable->entries[i].byuuid = NULL;
-               _reg_htable->entries[i].isize=0;
-               it = _reg_htable->entries[i].byuser;
+               _reg_htable_gc->entries[i].byuuid = NULL;
+               _reg_htable_gc->entries[i].isize=0;
+               it = _reg_htable_gc->entries[i].byuser;
                while(it)
                {
                        it0 = it;
@@ -282,10 +364,48 @@ int uac_reg_reset_ht(void)
                        shm_free(it0->r);
                        shm_free(it0);
                }
+               _reg_htable_gc->entries[i].byuser = NULL;
+               _reg_htable_gc->entries[i].usize = 0;
+       }
+       return 0;
+}
+
+/**
+ *
+ */
+int uac_reg_ht_shift(void)
+{
+       time_t tn;
+       int i;
+
+       if(_reg_htable==NULL || _reg_htable_gc==NULL)
+       {
+               LM_ERR("data struct invalid\n");
+               return -1;
+       }
+       tn = time(NULL);
+
+       lock_get(_reg_htable_gc_lock);
+       if(_reg_htable_gc->stime > tn-UAC_REG_GC_INTERVAL) {
+               lock_release(_reg_htable_gc_lock);
+               LM_ERR("shifting the memory table is not possible in less than 
%d\n", UAC_REG_GC_INTERVAL);
+               return -1;
+       }
+       uac_reg_reset_ht_gc();
+       for(i=0; i<_reg_htable->htsize; i++)
+       {
+               /* shift entries */
+               _reg_htable_gc->entries[i].byuuid = 
_reg_htable->entries[i].byuuid;
+               _reg_htable_gc->entries[i].byuser = 
_reg_htable->entries[i].byuser;
+               _reg_htable_gc->stime = time(NULL);
+
+               /* reset active table entries */
+               _reg_htable->entries[i].byuuid = NULL;
+               _reg_htable->entries[i].isize=0;
                _reg_htable->entries[i].byuser = NULL;
                _reg_htable->entries[i].usize = 0;
-               lock_release(&_reg_htable->entries[i].lock);
        }
+       lock_release(_reg_htable_gc_lock);
        return 0;
 }
 
@@ -989,12 +1109,16 @@ int uac_reg_load_db(void)
                }
        }  while(RES_ROW_N(db_res)>0);
        reg_dbf.free_result(reg_db_con, db_res);
+       reg_dbf.close(reg_db_con);
 
 done:
        return 0;
 
 error:
-       reg_dbf.free_result(reg_db_con, db_res);
+       if (reg_db_con) {
+               reg_dbf.free_result(reg_db_con, db_res);
+               reg_dbf.close(reg_db_con);
+       }
        return -1;
 }
 
@@ -1385,13 +1509,33 @@ static void rpc_uac_reg_disable(rpc_t* rpc, void* ctx)
        rpc_uac_reg_update_flag(rpc, ctx, 0, UAC_REG_DISABLED);
 }
 
+static const char* rpc_uac_reg_reload_doc[2] = {
+       "Reload records from database.",
+       0
+};
 
+static void rpc_uac_reg_reload(rpc_t* rpc, void* ctx)
+{
+       int ret;
+       if(uac_reg_ht_shift()<0) {
+               rpc->fault(ctx, 500, "Failed to shift records - check log 
messages");
+               return;
+       }
+       lock_get(_reg_htable_gc_lock);
+       ret =  uac_reg_load_db();
+       lock_release(_reg_htable_gc_lock);
+       if(ret<0) {
+               rpc->fault(ctx, 500, "Failed to reload records - check log 
messages");
+               return;
+       }
+}
 
 rpc_export_t uac_reg_rpc[] = {
        {"uac.reg_dump", rpc_uac_reg_dump, rpc_uac_reg_dump_doc, 0},
        {"uac.reg_info", rpc_uac_reg_info, rpc_uac_reg_info_doc, 0},
        {"uac.reg_enable",  rpc_uac_reg_enable,  rpc_uac_reg_enable_doc,  0},
        {"uac.reg_disable", rpc_uac_reg_disable, rpc_uac_reg_disable_doc, 0},
+       {"uac.reg_reload",  rpc_uac_reg_reload,  rpc_uac_reg_reload_doc,  0},
        {0, 0, 0, 0}
 };
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to