Module: sip-router
Branch: master
Commit: bc5cc684efad11f9affe648f3d0f6da98e43ad25
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=bc5cc68…
Author: Elena-Ramona Modroiu <ramona(a)asipto.com>
Committer: Elena-Ramona Modroiu <ramona(a)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)
{