Jelajahi Sumber

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
Andrei Pelinescu-Onciul 14 tahun lalu
induk
melakukan
1699b6a4c4
2 mengubah file dengan 20 tambahan dan 2 penghapusan
  1. 18 2
      modules/tm/h_table.c
  2. 2 0
      modules/tm/h_table.h

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

+ 2 - 0
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