Переглянути джерело

Kamailio compatiblity: Added pointer to a free function to tm callbacks

This patch adds a new pointer to the tm_callback structure. The
parameter contains pointer to a function which, if not NULL, will be
called to dispose the callback parameter when it is not needed anymore.

This is useful if the parameter given ti a transaction callback is a
complex data structure of it is stored on the heap and the memory needs
to be free when the corresponding transaction is being destroyed.

Patch contributed by Ovidiu Sas.
Jan Janak 16 роки тому
батько
коміт
657f117b85
5 змінених файлів з 22 додано та 8 видалено
  1. 1 1
      modules/tm/dlg.c
  2. 3 0
      modules/tm/h_table.c
  3. 6 3
      modules/tm/t_hooks.c
  4. 10 3
      modules/tm/t_hooks.h
  5. 2 1
      modules/tm/uac.c

+ 1 - 1
modules/tm/dlg.c

@@ -126,7 +126,7 @@ int register_dlg_tmcb(int types, dlg_t* dlg, transaction_cb f, void* param)
 		LOG(L_CRIT, "BUG: tm: register_dlg_tmcb: null callback function");
 		return E_BUG;
 	}
-	return insert_tmcb(&dlg->dlg_callbacks, types, f, param);
+	return insert_tmcb(&dlg->dlg_callbacks, types, f, param, NULL);
 }
 
 

+ 3 - 0
modules/tm/h_table.c

@@ -141,6 +141,9 @@ void free_cell( struct cell* dead_cell )
 	for( cbs=(struct tm_callback*)dead_cell->tmcb_hl.first ; cbs ; ) {
 		cbs_tmp = cbs;
 		cbs = cbs->next;
+		if (cbs_tmp->release) {
+			cbs_tmp->release(cbs_tmp->param);
+		}
 		shm_free_unsafe( cbs_tmp );
 	}
 

+ 6 - 3
modules/tm/t_hooks.c

@@ -117,7 +117,8 @@ void destroy_tmcb_lists()
 
 /* lockless insert: should be always safe */
 int insert_tmcb(struct tmcb_head_list *cb_list, int types,
-									transaction_cb f, void *param )
+				transaction_cb f, void *param,
+				release_tmcb_param rel_func)
 {
 	struct tm_callback *cbp;
 	struct tm_callback *old;
@@ -133,6 +134,7 @@ int insert_tmcb(struct tmcb_head_list *cb_list, int types,
 	/* ... and fill it up */
 	cbp->callback = f;
 	cbp->param = param;
+	cbp->release = rel_func;
 	cbp->types = types;
 	cbp->id=0;
 	old=(struct tm_callback*)cb_list->first;
@@ -164,7 +166,8 @@ int insert_tmcb(struct tmcb_head_list *cb_list, int types,
  *                 from mod_init (before forking!).
 */
 int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
-											transaction_cb f, void *param )
+				   transaction_cb f, void *param,
+				   release_tmcb_param rel_func)
 {
 	//struct cell* t;
 	struct tmcb_head_list *cb_list;
@@ -217,7 +220,7 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
 		cb_list = &(t->tmcb_hl);
 	}
 
-	return insert_tmcb( cb_list, types, f, param );
+	return insert_tmcb( cb_list, types, f, param, rel_func );
 }
 
 

+ 10 - 3
modules/tm/t_hooks.h

@@ -385,9 +385,12 @@ do{ \
 
 /* callback function prototype */
 typedef void (transaction_cb) (struct cell* t, int type, struct tmcb_params*);
+/*! \brief function to release the callback param */
+typedef void (release_tmcb_param) (void* param);
 /* register callback function prototype */
 typedef int (*register_tmcb_f)(struct sip_msg* p_msg, struct cell *t,
-		int cb_types, transaction_cb f, void *param);
+							   int cb_types, transaction_cb f, void *param,
+							   release_tmcb_param func);
 
 
 struct tm_callback {
@@ -395,6 +398,8 @@ struct tm_callback {
 	int types;                   /* types of events that trigger the callback*/
 	transaction_cb* callback;    /* callback function */
 	void *param;                 /* param to be passed to callback function */
+	release_tmcb_param* release; /**< Function to release the callback param
+								  * when the callback is deleted */
 	struct tm_callback* next;
 };
 
@@ -423,11 +428,13 @@ void destroy_tmcb_lists();
 
 /* register a callback for several types of events */
 int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
-											transaction_cb f, void *param );
+				   transaction_cb f, void *param,
+				   release_tmcb_param rel_func);
 
 /* inserts a callback into the a callback list */
 int insert_tmcb(struct tmcb_head_list *cb_list, int types,
-									transaction_cb f, void *param );
+				transaction_cb f, void *param,
+				release_tmcb_param rel_func);
 
 /* run all transaction callbacks for an event type */
 void run_trans_callbacks( int type , struct cell *trans,

+ 2 - 1
modules/tm/uac.c

@@ -319,7 +319,8 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 	/* Register the callbacks after everything is successful and nothing can fail.
 	Otherwise the callback parameter would be freed twise, once from TMCB_DESTROY,
 	and again because of the negative return code. */
-	if(uac_r->cb && insert_tmcb(&(new_cell->tmcb_hl), uac_r->cb_flags, *(uac_r->cb), uac_r->cbp)!=1){
+	if(uac_r->cb && insert_tmcb(&(new_cell->tmcb_hl), uac_r->cb_flags, 
+								*(uac_r->cb), uac_r->cbp, NULL)!=1){
 		ret=E_OUT_OF_MEM; 
 		LOG(L_ERR, "t_uac: short of tmcb shmem\n");
 		goto error1;