Module: kamailio
Branch: 5.1
Commit: 8aebe3b9009cc682ed1d1fefb599bef190b47a09
URL:
https://github.com/kamailio/kamailio/commit/8aebe3b9009cc682ed1d1fefb599bef…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: 2018-06-21T08:27:32+02:00
tm: force free cell in UNREF_FREE() if transaction is unlinkled from timers
(cherry picked from commit 72f5eaeeef0239ebd16a2d645b83e83eb1a2b506)
---
Modified: src/modules/tm/t_funcs.h
Modified: src/modules/tm/timer.c
Modified: src/modules/tm/timer.h
Modified: src/modules/tm/uac.c
---
Diff:
https://github.com/kamailio/kamailio/commit/8aebe3b9009cc682ed1d1fefb599bef…
Patch:
https://github.com/kamailio/kamailio/commit/8aebe3b9009cc682ed1d1fefb599bef…
---
diff --git a/src/modules/tm/t_funcs.h b/src/modules/tm/t_funcs.h
index bbab42482f..5c219ca02f 100644
--- a/src/modules/tm/t_funcs.h
+++ b/src/modules/tm/t_funcs.h
@@ -96,13 +96,18 @@ int send_pr_buffer( struct retr_buf *rb, void *buf, int len);
#ifdef TM_DEL_UNREF
-#define UNREF_FREE(_T_cell) \
+#define UNREF_FREE(_T_cell, _T_unlinked) \
do{\
if (atomic_dec_and_test(&(_T_cell)->ref_count)){ \
unlink_timers((_T_cell)); \
free_cell((_T_cell)); \
- }else \
- t_stats_delayed_free(); \
+ }else{ \
+ if(_T_unlinked){ \
+ free_cell((_T_cell)); \
+ }else{ \
+ t_stats_delayed_free(); \
+ } \
+ } \
}while(0)
#define UNREF_NOSTATS(_T_cell) \
diff --git a/src/modules/tm/timer.c b/src/modules/tm/timer.c
index 996efbc21c..b5e4325929 100644
--- a/src/modules/tm/timer.c
+++ b/src/modules/tm/timer.c
@@ -648,7 +648,11 @@ ticks_t wait_handler(ticks_t ti, struct timer_ln *wait_tl, void
*data)
remove_from_hash_table_unsafe(p_cell);
UNLOCK_HASH(p_cell->hash_index);
p_cell->flags |= T_IN_AGONY;
- UNREF_FREE(p_cell);
+ if(t_linked_timers(p_cell)) {
+ UNREF_FREE(p_cell, 0);
+ } else {
+ UNREF_FREE(p_cell, 1);
+ }
ret = 0;
#else /* TM_DEL_UNREF */
if(p_cell->flags & T_IN_AGONY) {
diff --git a/src/modules/tm/timer.h b/src/modules/tm/timer.h
index 3bdb16a65a..5cb6c736a6 100644
--- a/src/modules/tm/timer.h
+++ b/src/modules/tm/timer.h
@@ -375,5 +375,24 @@ inline static void unlink_timers(struct cell *t)
cleanup_localcancel_timers(t);
}
+inline static int t_linked_timers(tm_cell_t *t)
+{
+ int i;
+
+ if(t->uas.response.timer.next!=NULL || t->uas.response.timer.prev!=NULL) {
+ return 1;
+ }
+ for(i = 0; i < t->nr_of_outgoings; i++) {
+ if(t->uac[i].request.timer.next!=NULL
+ || t->uac[i].request.timer.prev!=NULL) {
+ return 1;
+ }
+ if(t->uac[i].local_cancel.timer.next!=NULL
+ || t->uac[i].local_cancel.timer.prev!=NULL) {
+ return 1;
+ }
+ }
+ return 0;
+}
#endif
diff --git a/src/modules/tm/uac.c b/src/modules/tm/uac.c
index 9b2f51b5f6..42e25762d2 100644
--- a/src/modules/tm/uac.c
+++ b/src/modules/tm/uac.c
@@ -589,7 +589,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
if(atomic_get_int(&new_cell->ref_count)==0) {
free_cell(new_cell);
} else {
- UNREF_FREE(new_cell);
+ UNREF_FREE(new_cell, 0);
}
}
#else