Module: kamailio Branch: 5.1 Commit: 8aebe3b9009cc682ed1d1fefb599bef190b47a09 URL: https://github.com/kamailio/kamailio/commit/8aebe3b9009cc682ed1d1fefb599bef1...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@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/8aebe3b9009cc682ed1d1fefb599bef1... Patch: https://github.com/kamailio/kamailio/commit/8aebe3b9009cc682ed1d1fefb599bef1...
---
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