diff --git a/modules/tm/defs.h b/modules/tm/defs.h index 1e08b950786..b712b1d3c5d 100644 --- a/modules/tm/defs.h +++ b/modules/tm/defs.h @@ -30,5 +30,9 @@ #ifndef _TM_DEFS_H #define _TM_DEFS_H +/* CANCEL_REASON_SUPPORT on by default */ +#ifndef NO_CANCEL_REASON_SUPPORT +#define CANCEL_REASON_SUPPORT +#endif /* NO_CANCEL_REASON_SUPPORT */ #endif diff --git a/modules/tm/h_table.h b/modules/tm/h_table.h index 52b6d2cf4ac..18382453c1f 100644 --- a/modules/tm/h_table.h +++ b/modules/tm/h_table.h @@ -75,7 +75,6 @@ struct async_state; #include "../../mem/shm_mem.h" #include "lock.h" #include "sip_msg.h" -#include "t_reply.h" #include "t_hooks.h" #ifdef USE_DNS_FAILOVER #include "../../dns_cache.h" @@ -428,7 +427,12 @@ typedef struct cell #endif /* protection against concurrent reply processing */ - ser_lock_t reply_mutex; + ser_lock_t reply_mutex; + /* pid of the process that holds the reply lock */ + atomic_t reply_locker_pid; + /* recursive reply lock count */ + int reply_rec_lock_level; + /* protect against concurrent async continues */ ser_lock_t async_mutex; diff --git a/modules/tm/t_append_branches.c b/modules/tm/t_append_branches.c index ab6f298b8b7..b276d9e9182 100644 --- a/modules/tm/t_append_branches.c +++ b/modules/tm/t_append_branches.c @@ -43,6 +43,7 @@ #include "t_msgbuilder.h" #include "t_lookup.h" #include "t_fwd.h" +#include "t_reply.h" #include "t_append_branches.h" int t_append_branches(void) { diff --git a/modules/tm/t_funcs.c b/modules/tm/t_funcs.c index 8e04de6faa0..cec58e03a65 100644 --- a/modules/tm/t_funcs.c +++ b/modules/tm/t_funcs.c @@ -36,6 +36,7 @@ #include "t_funcs.h" #include "t_fwd.h" #include "t_lookup.h" +#include "t_reply.h" #include "config.h" #include "t_stats.h" diff --git a/modules/tm/t_fwd.c b/modules/tm/t_fwd.c index 9fcf3813eea..9cd002f891a 100644 --- a/modules/tm/t_fwd.c +++ b/modules/tm/t_fwd.c @@ -44,6 +44,8 @@ #include "t_cancel.h" #include "t_lookup.h" #include "t_fwd.h" +#include "t_reply.h" +#include "h_table.h" #include "../../fix_lumps.h" #include "config.h" #ifdef USE_DNS_FAILOVER diff --git a/modules/tm/t_msgbuilder.h b/modules/tm/t_msgbuilder.h index ae09f31d566..4ede95b900a 100644 --- a/modules/tm/t_msgbuilder.h +++ b/modules/tm/t_msgbuilder.h @@ -27,6 +27,7 @@ #include "defs.h" #include "dlg.h" #include "h_table.h" +#include "t_reply.h" #define CSEQ "CSeq: " diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c index b5909c73702..5dfbfd0dbda 100644 --- a/modules/tm/t_reply.c +++ b/modules/tm/t_reply.c @@ -2775,3 +2775,34 @@ void rpc_reply(rpc_t* rpc, void* c) return; } } + +/** + * re-entrant locking of reply mutex + */ +void tm_reply_mutex_lock(tm_cell_t *t) +{ + int mypid; + + mypid = my_pid(); + if (likely(atomic_get(&t->reply_locker_pid) != mypid)) { + lock(&t->reply_mutex); + atomic_set(&t->reply_locker_pid, mypid); + } else { + /* locked within the same process that called us*/ + t->reply_rec_lock_level++; + } +} + +/** + * re-entrant unlocking of reply mutex + */ +void tm_reply_mutex_unlock(tm_cell_t *t) +{ + if (likely(t->reply_rec_lock_level == 0)) { + atomic_set(&t->reply_locker_pid, 0); + unlock(&t->reply_mutex); + } else { + /* recursive locked => decrease rec. lock count */ + t->reply_rec_lock_level--; + } +} diff --git a/modules/tm/t_reply.h b/modules/tm/t_reply.h index 2151e4a7d68..91b2ac839ce 100644 --- a/modules/tm/t_reply.h +++ b/modules/tm/t_reply.h @@ -23,11 +23,6 @@ #ifndef _T_REPLY_H #define _T_REPLY_H -/* CANCEL_REASON_SUPPORT on by default */ -#ifndef NO_CANCEL_REASON_SUPPORT -#define CANCEL_REASON_SUPPORT -#endif /* NO_CANCEL_REASON_SUPPORT */ - #include "defs.h" #include "../../rpc.h" #include "../../tags.h" @@ -139,8 +134,11 @@ int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt); typedef int (*tget_reply_totag_f)(struct sip_msg *, str *); int t_get_reply_totag(struct sip_msg *msg, str *totag); -#define LOCK_REPLIES(_t) lock(&(_t)->reply_mutex ) -#define UNLOCK_REPLIES(_t) unlock(&(_t)->reply_mutex ) +void tm_reply_mutex_lock(tm_cell_t *t); +void tm_reply_mutex_unlock(tm_cell_t *t); + +#define LOCK_REPLIES(_t) tm_reply_mutex_lock((_t)) +#define UNLOCK_REPLIES(_t) tm_reply_mutex_unlock((_t)) /* This function is called whenever a reply for our module is received; * we need to register this function on module initialization; diff --git a/modules/tm/t_serial.c b/modules/tm/t_serial.c index 0bc671d3e01..b3207599d39 100644 --- a/modules/tm/t_serial.c +++ b/modules/tm/t_serial.c @@ -34,6 +34,7 @@ #include "../../ut.h" #include "config.h" #include "t_funcs.h" +#include "t_reply.h" #include "t_lookup.h" /* usr_avp flag for sequential forking */