Module: sip-router Branch: 3.1 Commit: 06b74b600e6644f4bf289d256538d463f6734717 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=06b74b60...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Fri Apr 29 19:40:36 2011 +0200
tm: recursive hash locks
The hash locks are now recursive/re-entrant. This removes some of the TMCB_REQUEST_IN and TMCB_LOCAL_REQUEST_IN callback restrictions (like do not create new transactions, do not call t_lookup_*()) solving problems like the one described in http://lists.sip-router.org/pipermail/sr-users/2011-April/068331.html (cherry picked from commit 1699b6a4c479031c116fb081a805635a4d088bcb)
---
modules/tm/h_table.c | 20 ++++++++++++++++++-- modules/tm/h_table.h | 2 ++ 2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/modules/tm/h_table.c b/modules/tm/h_table.c index 33e72d7..c82f0b9 100644 --- a/modules/tm/h_table.c +++ b/modules/tm/h_table.c @@ -97,13 +97,29 @@ enum kill_reason get_kr() {
void lock_hash(int i) { - lock(&_tm_table->entries[i].mutex); + + int mypid; + + mypid = my_pid(); + if (likely(atomic_get(&_tm_table->entries[i].locker_pid) != mypid)) { + lock(&_tm_table->entries[i].mutex); + atomic_set(&_tm_table->entries[i].locker_pid, mypid); + } else { + /* locked within the same process that called us*/ + _tm_table->entries[i].rec_lock_level++; + } }
void unlock_hash(int i) { - unlock(&_tm_table->entries[i].mutex); + if (likely(_tm_table->entries[i].rec_lock_level == 0)) { + atomic_set(&_tm_table->entries[i].locker_pid, 0); + unlock(&_tm_table->entries[i].mutex); + } else { + /* recursive locked => decrease rec. lock count */ + _tm_table->entries[i].rec_lock_level--; + } }
diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h index 784606e..ea2fa14 100644 --- a/modules/tm/h_table.h +++ b/modules/tm/h_table.h @@ -429,6 +429,8 @@ typedef struct entry struct cell* prev_c; /* sync mutex */ ser_lock_t mutex; + atomic_t locker_pid; /* pid of the process that holds the lock */ + int rec_lock_level; /* recursive lock count */ /* currently highest sequence number in a synonym list */ unsigned int next_label; #ifdef TM_HASH_STATS