Module: sip-router Branch: tmp/k3.0_sr_backports Commit: 94942cbab5774f60100dbdfec0eb31dec4f2cff2 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=94942cba...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Fri Jan 15 22:09:01 2010 +0100
tm: run release function for tmcb parameters
- allow early registration of tm cb (in use by k uac module for example, reported by Vulpyne) - release function calling was missing (cherry picked from commit 68d63835c6ec1a3fa4984aa3eb3fcc081a4f1f86)
---
modules/tm/h_table.c | 5 +++- modules/tm/t_hooks.c | 51 +++++++++++++++++++++++++++++++++++++++---------- modules/tm/t_hooks.h | 2 + 3 files changed, 46 insertions(+), 12 deletions(-)
diff --git a/modules/tm/h_table.c b/modules/tm/h_table.c index f35d7d5..a7327d9 100644 --- a/modules/tm/h_table.c +++ b/modules/tm/h_table.c @@ -324,8 +324,11 @@ struct cell* build_cell( struct sip_msg* p_msg )
/* enter callback, which may potentially want to parse some stuff, * before the request is shmem-ized */ - if (p_msg && has_reqin_tmcbs()) + if (p_msg) { + set_early_tmcb_list(p_msg, new_cell); + if(has_reqin_tmcbs()) run_reqin_callbacks( new_cell, p_msg, p_msg->REQ_METHOD); + }
if (p_msg) { #ifndef POSTPONE_MSG_CLONING diff --git a/modules/tm/t_hooks.c b/modules/tm/t_hooks.c index 259476c..7698517 100644 --- a/modules/tm/t_hooks.c +++ b/modules/tm/t_hooks.c @@ -57,7 +57,36 @@ struct tmcb_head_list* req_in_tmcb_hl = 0; struct tmcb_head_list* local_req_in_tmcb_hl = 0;
+struct tm_early_cb { + unsigned int msgid; + struct tmcb_head_list cb_list; +} tmcb_early_hl = { 0, {0, 0} };
+struct tmcb_head_list* get_early_tmcb_list(struct sip_msg *msg) +{ + struct tm_callback *cbp, *cbp_tmp; + if (msg->id!=tmcb_early_hl.msgid) { + for( cbp=(struct tm_callback*)tmcb_early_hl.cb_list.first; cbp ; ) { + cbp_tmp = cbp; + cbp = cbp->next; + if (cbp_tmp->param && cbp_tmp->release) + cbp_tmp->release( cbp_tmp->param ); + shm_free( cbp_tmp ); + } + memset(&tmcb_early_hl.cb_list, 0, sizeof(struct tmcb_head_list)); + tmcb_early_hl.msgid = msg->id; + } + return &tmcb_early_hl.cb_list; +} + +void set_early_tmcb_list(struct sip_msg *msg, struct cell *t) +{ + if (msg->id!=tmcb_early_hl.msgid) { + t->tmcb_hl = tmcb_early_hl.cb_list; + memset(&tmcb_early_hl.cb_list, 0, sizeof(struct tmcb_head_list)); + tmcb_early_hl.msgid = 0; + } +}
int init_tmcb_lists() { @@ -95,7 +124,8 @@ void destroy_tmcb_lists() for( cbp=(struct tm_callback*)req_in_tmcb_hl->first; cbp ; ) { cbp_tmp = cbp; cbp = cbp->next; - if (cbp_tmp->param) shm_free( cbp_tmp->param ); + if (cbp_tmp->param && cbp_tmp->release) + cbp_tmp->release( cbp_tmp->param ); shm_free( cbp_tmp ); } shm_free(req_in_tmcb_hl); @@ -105,7 +135,8 @@ void destroy_tmcb_lists() for( cbp=(struct tm_callback*)local_req_in_tmcb_hl->first; cbp ; ) { cbp_tmp = cbp; cbp = cbp->next; - if (cbp_tmp->param) shm_free( cbp_tmp->param ); + if (cbp_tmp->param && cbp_tmp->release) + cbp_tmp->release( cbp_tmp->param ); shm_free( cbp_tmp ); } shm_free(local_req_in_tmcb_hl); @@ -207,17 +238,15 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types, return E_BUG; } /* look for the transaction */ - if ( t_check(p_msg,0)!=1 ){ - LOG(L_CRIT,"BUG:tm:register_tmcb: no transaction found\n"); - return E_BUG; - } - if ( (t=get_t())==0 ) { - LOG(L_CRIT,"BUG:tm:register_tmcb: transaction found " - "is NULL\n"); - return E_BUG; + t=get_t(); + if ( t!=0 && t!=T_UNDEFINED) { + cb_list = &(t->tmcb_hl); + } else { + cb_list = get_early_tmcb_list(p_msg); } + } else { + cb_list = &(t->tmcb_hl); } - cb_list = &(t->tmcb_hl); }
return insert_tmcb( cb_list, types, f, param, rel_func ); diff --git a/modules/tm/t_hooks.h b/modules/tm/t_hooks.h index d593a67..32ebaa3 100644 --- a/modules/tm/t_hooks.h +++ b/modules/tm/t_hooks.h @@ -418,6 +418,8 @@ struct tmcb_head_list { extern struct tmcb_head_list* req_in_tmcb_hl; extern struct tmcb_head_list* local_req_in_tmcb_hl;
+void set_early_tmcb_list(struct sip_msg *msg, + struct cell *t);
#define has_tran_tmcbs(_T_, _types_) \ ( ((_T_)->tmcb_hl.reg_types)&(_types_) )