Browse Source

tm: which_cancel renamed and takes more parameters

- which_cancel() renamed to prepare_to_cancel() to better reflect
  its real purpose.
- which_cancel_f renamed to prepare_to_cancel_f
- tm_binds which_cancel member renamed to prepare_to_cancel
- should_cancel_branch() renamed to prepare_cancel_branch().
- prepare_to_cancel() takes now an extra parameter (skip_branches)
  which contains a bitmap of the branches that should be skipped
  (not canceled).
Andrei Pelinescu-Onciul 16 năm trước cách đây
mục cha
commit
79edcdf278

+ 26 - 12
modules/tm/t_cancel.c

@@ -42,6 +42,10 @@
  * 2008-03-08  e2e_cancel handles non replied branches in 3 different ways,
  *              selectable by the tm cancel_b_method parameter: fake reply,
  *              retransmit request and send cancel on branch (andrei)
+ * 2009-07-14  renamed which_cancel() to prepare_to_cancel() for better
+ *              reflecting its purpose
+ *             prepare_to_cancel() takes now an additional skip_branches
+ *              bitmap parameter (andrei)
  */
 
 #include <stdio.h> /* for FILE* in fifo_uac_cancel */
@@ -62,13 +66,23 @@
 #include "t_hooks.h"
 
 
-/* determine which branches should be canceled; can be called 
-   without REPLY_LOCK, since should_cancel_branch() is atomic now
-   -- andrei
- WARNING: - has side effects, see should_cancel_branch()
-          - one _must_ call cancel_uacs(cancel_bm) if *cancel_bm!=0 or
-            you'll have some un-cancelable branches */
-void which_cancel( struct cell *t, branch_bm_t *cancel_bm )
+/** Prepare to cancel a transaction.
+ * Determine which branches should be canceled and prepare them (internally
+ * mark them as "cancel in progress", see prepare_cancel_branch()).
+ * Can be called without REPLY_LOCK, since prepare_cancel_branch() is atomic 
+ *  now *  -- andrei
+ * WARNING: - has side effects, see prepare_cancel_branch()
+ *          - one _must_ call cancel_uacs(cancel_bm) if *cancel_bm!=0 or
+ *             you'll have some un-cancelable branches (because they remain
+ *             "marked" internally)
+ * @param t - transaction whose branches will be canceled
+ * @param cancel_bm - pointer to a branch bitmap that will be filled with
+*    the branches that must be canceled (must be passed to cancel_uacs() if
+*    !=0).
+*  @param skip - branch bitmap of branches that should not be canceled
+*/
+void prepare_to_cancel(struct cell *t, branch_bm_t *cancel_bm,
+						branch_bm_t skip_branches)
 {
 	int i;
 	int branches_no;
@@ -77,7 +91,7 @@ void which_cancel( struct cell *t, branch_bm_t *cancel_bm )
 	branches_no=t->nr_of_outgoings;
 	membar_depends(); 
 	for( i=0 ; i<branches_no ; i++ ) {
-		if (should_cancel_branch(t, i, 1)) 
+		if (!(skip_branches & (1<<i)) &&  prepare_cancel_branch(t, i, 1))
 			*cancel_bm |= 1<<i ;
 	}
 }
@@ -91,7 +105,7 @@ void which_cancel( struct cell *t, branch_bm_t *cancel_bm )
  *                       canceled 
  *          flags     - how_to_cancel flags, see cancel_branch()
  * returns: bitmap with the still active branches (on fr timer)
- * WARNING: always fill cancel_bm using which_cancel(), supplying values
+ * WARNING: always fill cancel_bm using prepare_to_cancel(), supplying values
  *          in any other way is a bug*/
 int cancel_uacs( struct cell *t, branch_bm_t cancel_bm, int flags)
 {
@@ -125,7 +139,7 @@ int cancel_all_uacs(struct cell *trans, int how)
 	DBG("Canceling T@%p [%u:%u]\n", trans, trans->hash_index, trans->label);
 	
 	cancel_bm=0;
-	which_cancel(trans, &cancel_bm);
+	prepare_to_cancel(trans, &cancel_bm, 0);
 	 /* tell tm to cancel the call */
 	i=cancel_uacs(trans, cancel_bm, how);
 	
@@ -151,7 +165,7 @@ int cancel_all_uacs(struct cell *trans, int how)
 
 
 /* should be called directly only if one of the condition bellow is true:
- *  - should_cancel_branch or which_cancel returned true for this branch
+ *  - prepare_cancel_branch or prepare_to_cancel returned true for this branch
  *  - buffer value was 0 and then set to BUSY in an atomic op.:
  *     if (atomic_cmpxchg_long(&buffer, 0, BUSY_BUFFER)==0).
  *
@@ -346,7 +360,7 @@ void rpc_cancel(rpc_t* rpc, void* c)
 	}
 	/*  find the branches that need cancel-ing */
 	LOCK_REPLIES(trans);
-		which_cancel(trans, &cancel_bm);
+		prepare_to_cancel(trans, &cancel_bm, 0);
 	UNLOCK_REPLIES(trans);
 	 /* tell tm to cancel the call */
 	DBG("Now calling cancel_uacs\n");

+ 19 - 5
modules/tm/t_cancel.h

@@ -32,6 +32,9 @@
  *               no response or with response <100 (andrei)
  *  2007-06-04  should_cancel_branch() takes another parameter and it is safe
  *               to be called w/o REPLY_LOCK held (andrei)
+ *  2009-07-14  should_cancel_branch() renamed to prepare_cancel_branch() to
+ *               better reflect its purpose
+ *              which_cancel() renamed to prepare_to_cancel() (andrei)
  */
 
 
@@ -75,7 +78,7 @@
 #define F_CANCEL_UNREF 16 /* unref the trans after canceling */
 
 
-void which_cancel( struct cell *t, branch_bm_t *cancel_bm );
+void prepare_to_cancel(struct cell *t, branch_bm_t *cancel_bm, branch_bm_t s);
 int cancel_uacs( struct cell *t, branch_bm_t cancel_bm, int flags );
 int cancel_all_uacs(struct cell *trans, int how);
 int cancel_branch( struct cell *t, int branch, int flags );
@@ -84,10 +87,11 @@ typedef int(*cancel_uacs_f)( struct cell *t, branch_bm_t cancel_bm,
 								int flags );
 typedef int (*cancel_all_uacs_f)(struct cell *trans, int how);
 
-typedef void (*which_cancel_f)(struct cell *t, branch_bm_t *cancel_bm );
+typedef void (*prepare_to_cancel_f)(struct cell *t, branch_bm_t *cancel_bm,
+									branch_bm_t skip_branches);
 
 
-/* 
+/** Check if one branch needs CANCEL-ing and prepare it if it does.
  * Can be called w/o REPLY_LOCK held
  *  between this call and the call to cancel_uacs()/cancel_branch()
  *  if noreply is set to 1 it will return true even if no reply was received
@@ -96,8 +100,18 @@ typedef void (*which_cancel_f)(struct cell *t, branch_bm_t *cancel_bm );
  *  if noreply is set to 0 it will return true only if no cancel has already 
  *   been sent and a provisional (<200) reply >=100 was received.
  *  WARNING: has side effects: marks branches that should be canceled
- *   and a second call won't return them again */
-inline short static should_cancel_branch( struct cell *t, int b, int noreply )
+ *   and a second call won't return them again.
+ * @param t - transaction
+ * @param b - branch number
+ * @param noreply - 0 or 1. If 1 it will consider a branch with no replies
+ *  received so far as cancel-able. If 0 only branches that have received
+ * a provisional reply (>=100 <200) will be considered.
+ *
+ * @return 1 if the branch must be canceled (it will be internally marked as
+ *  cancel-in-progress) and 0 if it doesn't (either a CANCEL is not needed or a
+ *  CANCEL is in progress: somebody else is trying to CANCEL in the same time).
+ */
+inline short static prepare_cancel_branch( struct cell *t, int b, int noreply )
 {
 	int last_received;
 	unsigned long old;

+ 4 - 4
modules/tm/t_fwd.c

@@ -358,7 +358,7 @@ int add_blind_uac( /*struct cell *t*/ )
 	}
 	/* make sure it will be replied */
 	t->flags |= T_NOISY_CTIMER_FLAG;
-	membar_write(); /* to allow lockless which_cancel() we want to be sure 
+	membar_write(); /* to allow lockless prepare_to_cancel() we want to be sure
 					   all the writes finished before updating branch number*/
 	t->nr_of_outgoings=(branch+1);
 	/* start FR timer -- protocol set by default to PROTO_NONE,
@@ -460,7 +460,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
 		t->uac[branch].flags = TM_UAC_FLAG_RR|TM_UAC_FLAG_R2;
 #endif
 	getbflagsval(0, &t->uac[branch].branch_flags);
-	membar_write(); /* to allow lockless ops (e.g. which_cancel()) we want
+	membar_write(); /* to allow lockless ops (e.g. prepare_to_cancel()) we want
 					   to be sure everything above is fully written before
 					   updating branches no. */
 	t->nr_of_outgoings=(branch+1);
@@ -538,7 +538,7 @@ static int add_uac_from_buf( struct cell *t, struct sip_msg *request, str *uri,
 	t->uac[branch].uri.s=t->uac[branch].request.buffer+
 		request->first_line.u.request.method.len+1;
 	t->uac[branch].uri.len=uri->len;
-	membar_write(); /* to allow lockless ops (e.g. which_cancel()) we want
+	membar_write(); /* to allow lockless ops (e.g. prepare_to_cancel()) we want
 					   to be sure everything above is fully written before
 					   updating branches no. */
 	t->nr_of_outgoings=(branch+1);
@@ -729,7 +729,7 @@ void e2e_cancel( struct sip_msg *cancel_msg,
 	}
 	
 	/* determine which branches to cancel ... */
-	which_cancel( t_invite, &cancel_bm );
+	prepare_to_cancel(t_invite, &cancel_bm, 0);
 #ifdef E2E_CANCEL_HOP_BY_HOP
 	/* we don't need to set t_cancel label to be the same as t_invite if
 	 * we do hop by hop cancel. The cancel transaction will have a different 

+ 7 - 7
modules/tm/t_reply.c

@@ -523,7 +523,7 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
 		/* determine if there are some branches to be canceled */
 		if ( is_invite(trans) ) {
 			if (lock) LOCK_REPLIES( trans );
-			which_cancel(trans, &cancel_bitmap );
+			prepare_to_cancel(trans, &cancel_bitmap, 0);
 			if (lock) UNLOCK_REPLIES( trans );
 		}
 		/* and clean-up, including cancellations, if needed */
@@ -532,7 +532,7 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
 
 	cancel_bitmap=0;
 	if (lock) LOCK_REPLIES( trans );
-	if ( is_invite(trans) ) which_cancel(trans, &cancel_bitmap );
+	if ( is_invite(trans) ) prepare_to_cancel(trans, &cancel_bitmap, 0);
 	if (trans->uas.status>=200) {
 		LOG( L_ERR, "ERROR: _reply_light: can't generate %d reply"
 			" when a final %d was sent out\n", code, trans->uas.status);
@@ -1085,7 +1085,7 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 			if (new_code>=600 && new_code<=699){
 				if (!(Trans->flags & T_6xx)){
 					/* cancel only the first time we get a 6xx */
-					which_cancel(Trans, cancel_bitmap);
+					prepare_to_cancel(Trans, cancel_bitmap, 0);
 					Trans->flags|=T_6xx;
 				}
 			}
@@ -1205,9 +1205,9 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 		/* really no more pending branches -- return lowest code */
 		*should_store=0;
 		*should_relay=picked_branch;
-		/* we dont need 'which_cancel' here -- all branches
+		/* we dont need 'prepare_to_cancel' here -- all branches
 		   known to have completed */
-		/* which_cancel( Trans, cancel_bitmap ); */
+		/* prepare_to_cancel( Trans, cancel_bitmap, 0 ); */
 		return RPS_COMPLETED;
 	}
 
@@ -1225,7 +1225,7 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 		Trans->uac[branch].last_received=new_code;
 		*should_relay= new_code==100? -1 : branch;
 		if (new_code>=200 ) {
-			which_cancel( Trans, cancel_bitmap );
+			prepare_to_cancel( Trans, cancel_bitmap, 0);
 			return RPS_COMPLETED;
 		} else return RPS_PROVISIONAL;
 	}
@@ -1789,7 +1789,7 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
 	return reply_status;
 
 error:
-	which_cancel(t, cancel_bitmap);
+	prepare_to_cancel(t, cancel_bitmap, 0);
 	UNLOCK_REPLIES(t);
 	cleanup_uac_timers(t);
 	if ( get_cseq(p_msg)->method.len==INVITE_LEN

+ 1 - 1
modules/tm/timer.c

@@ -302,7 +302,7 @@ static void fake_reply(struct cell *t, int branch, int code )
 	short do_cancel_branch;
 	enum rps reply_status;
 
-	do_cancel_branch = is_invite(t) && should_cancel_branch(t, branch, 0);
+	do_cancel_branch = is_invite(t) && prepare_cancel_branch(t, branch, 0);
 	/* mark branch as canceled */
 	t->uac[branch].request.flags|=F_RB_CANCELED;
 	if ( is_local(t) ) {

+ 1 - 1
modules/tm/tm_load.c

@@ -235,7 +235,7 @@ int load_tm( struct tm_binds *tmb)
 	tmb->t_lookup_original = t_lookupOriginalT;
 	tmb->t_check = t_check;
 	tmb->unref_cell = unref_cell;
-	tmb->which_cancel = which_cancel;
+	tmb->prepare_to_cancel = prepare_to_cancel;
 	tmb->get_stats = tm_get_stats;
 
 #ifdef WITH_TM_CTX

+ 2 - 1
modules/tm/tm_load.h

@@ -28,6 +28,7 @@
  * History:
  * --------
  * 2003-03-06  voicemail changes accepted
+ * 2009-07-14  renamed which_cancel* to prepare_to_cancel* (andrei)
  *
  */
 
@@ -143,7 +144,7 @@ struct tm_binds {
 	tlookup_original_f t_lookup_original;
 	tcheck_f t_check;
 	unref_cell_f unref_cell;
-	which_cancel_f which_cancel;
+	prepare_to_cancel_f prepare_to_cancel;
 	tm_get_stats_f get_stats;
 #ifdef WITH_TM_CTX
 	tm_ctx_get_f tm_ctx_get;