[sr-dev] git:master: htable: two new functions to lock htable slots based on item name

Elena-Ramona Modroiu ramona at rosdev.ro
Wed Jul 10 11:24:20 CEST 2013


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

Author: Elena-Ramona Modroiu <ramona at asipto.com>
Committer: Elena-Ramona Modroiu <ramona at asipto.com>
Date:   Sat Jul  6 18:31:17 2013 +0200

htable: two new functions to lock htable slots based on item name

- sht_lock("htable=>key") and sht_unlock("htable=>key")
- useful to update existing items without aditional locks

---

 modules/htable/ht_api.c |    4 --
 modules/htable/ht_api.h |    3 +
 modules/htable/htable.c |   98 +++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 97 insertions(+), 8 deletions(-)

diff --git a/modules/htable/ht_api.c b/modules/htable/ht_api.c
index 6a74793..84eb2e0 100644
--- a/modules/htable/ht_api.c
+++ b/modules/htable/ht_api.c
@@ -36,10 +36,6 @@
 #include "ht_db.h"
 
 
-#define ht_compute_hash(_s)        core_case_hash(_s,0,0)
-#define ht_get_entry(_h,_size)    (_h)&((_size)-1)
-
-
 ht_t *_ht_root = NULL;
 
 typedef struct _keyvalue {
diff --git a/modules/htable/ht_api.h b/modules/htable/ht_api.h
index c8b88f7..98b2eae 100644
--- a/modules/htable/ht_api.h
+++ b/modules/htable/ht_api.h
@@ -29,6 +29,9 @@
 #include "../../locking.h"
 #include "../../pvar.h"
 
+#define ht_compute_hash(_s)        core_case_hash(_s,0,0)
+#define ht_get_entry(_h,_size)    (_h)&((_size)-1)
+
 typedef struct _ht_cell
 {
     unsigned int cellid;
diff --git a/modules/htable/htable.c b/modules/htable/htable.c
index 68a7a5b..37c68f4 100644
--- a/modules/htable/htable.c
+++ b/modules/htable/htable.c
@@ -32,6 +32,7 @@
 #include "../../timer.h"
 #include "../../route.h"
 #include "../../dprint.h"
+#include "../../hashes.h"
 #include "../../ut.h"
 #include "../../rpc.h"
 #include "../../rpc_lookup.h"
@@ -58,9 +59,11 @@ static int mod_init(void);
 static int child_init(int rank);
 static void destroy(void);
 
-static int fixup_ht_rm(void** param, int param_no);
+static int fixup_ht_key(void** param, int param_no);
 static int ht_rm_name_re(struct sip_msg* msg, char* key, char* foo);
 static int ht_rm_value_re(struct sip_msg* msg, char* key, char* foo);
+static int ht_slot_lock(struct sip_msg* msg, char* key, char* foo);
+static int ht_slot_unlock(struct sip_msg* msg, char* key, char* foo);
 
 int ht_param(modparam_t type, void* val);
 
@@ -96,9 +99,13 @@ static mi_export_t mi_cmds[] = {
 static cmd_export_t cmds[]={
 	{"sht_print",       (cmd_function)ht_print,        0, 0, 0,
 		ANY_ROUTE},
-	{"sht_rm_name_re",  (cmd_function)ht_rm_name_re,   1, fixup_ht_rm, 0,
+	{"sht_rm_name_re",  (cmd_function)ht_rm_name_re,   1, fixup_ht_key, 0,
 		ANY_ROUTE},
-	{"sht_rm_value_re", (cmd_function)ht_rm_value_re,  1, fixup_ht_rm, 0,
+	{"sht_rm_value_re", (cmd_function)ht_rm_value_re,  1, fixup_ht_key, 0,
+		ANY_ROUTE},
+	{"sht_lock",        (cmd_function)ht_slot_lock,    1, fixup_ht_key, 0,
+		ANY_ROUTE},
+	{"sht_unlock",      (cmd_function)ht_slot_unlock,  1, fixup_ht_key, 0,
 		ANY_ROUTE},
 	{"bind_htable",     (cmd_function)bind_htable,     0, 0, 0,
 		ANY_ROUTE},
@@ -245,7 +252,7 @@ static int ht_print(struct sip_msg *msg, char *s1, char *s2)
 	return 1;
 }
 
-static int fixup_ht_rm(void** param, int param_no)
+static int fixup_ht_key(void** param, int param_no)
 {
 	pv_spec_t *sp;
 	str s;
@@ -324,6 +331,89 @@ static int ht_rm_value_re(struct sip_msg* msg, char* key, char* foo)
 	return 1;
 }
 
+/**
+ * lock the slot for a given key in a hash table
+ */
+static int ht_slot_lock(struct sip_msg* msg, char* key, char* foo)
+{
+	ht_pv_t *hpv;
+	str skey;
+	pv_spec_t *sp;
+	unsigned int hid;
+	unsigned int idx;
+
+	sp = (pv_spec_t*)key;
+
+	hpv = (ht_pv_t*)sp->pvp.pvn.u.dname;
+
+	if(hpv->ht==NULL)
+	{
+		hpv->ht = ht_get_table(&hpv->htname);
+		if(hpv->ht==NULL) {
+			LM_ERR("cannot get $ht root\n");
+			return -11;
+		}
+	}
+	if(pv_printf_s(msg, hpv->pve, &skey)!=0)
+	{
+		LM_ERR("cannot get $ht key\n");
+		return -1;
+	}
+
+	hid = ht_compute_hash(&skey);
+
+	idx = ht_get_entry(hid, hpv->ht->htsize);
+
+	LM_DBG("unlocking slot %.*s[%u] for key %.*s\n",
+			hpv->htname.len, hpv->htname.s,
+			idx, skey.len, skey.s);
+
+	lock_get(&hpv->ht->entries[idx].lock);
+
+	return 1;
+}
+
+/**
+ * unlock the slot for a given key in a hash table
+ */
+static int ht_slot_unlock(struct sip_msg* msg, char* key, char* foo)
+{
+	ht_pv_t *hpv;
+	str skey;
+	pv_spec_t *sp;
+	unsigned int hid;
+	unsigned int idx;
+
+	sp = (pv_spec_t*)key;
+
+	hpv = (ht_pv_t*)sp->pvp.pvn.u.dname;
+
+	if(hpv->ht==NULL)
+	{
+		hpv->ht = ht_get_table(&hpv->htname);
+		if(hpv->ht==NULL) {
+			LM_ERR("cannot get $ht root\n");
+			return -11;
+		}
+	}
+	if(pv_printf_s(msg, hpv->pve, &skey)!=0)
+	{
+		LM_ERR("cannot get $ht key\n");
+		return -1;
+	}
+
+	hid = ht_compute_hash(&skey);
+
+	idx = ht_get_entry(hid, hpv->ht->htsize);
+
+	LM_DBG("unlocking slot %.*s[%u] for key %.*s\n",
+			hpv->htname.len, hpv->htname.s,
+			idx, skey.len, skey.s);
+
+	lock_release(&hpv->ht->entries[idx].lock);
+
+	return 1;
+}
 
 int ht_param(modparam_t type, void *val)
 {




More information about the sr-dev mailing list