示例#1
0
文件: timer.c 项目: btriller/kamailio
/* generate a fake reply
 * it assumes the REPLY_LOCK is already held and returns unlocked */
static void fake_reply(struct cell *t, int branch, int code)
{
	struct cancel_info cancel_data;
	short do_cancel_branch;
	enum rps reply_status;

	init_cancel_info(&cancel_data);
	do_cancel_branch = is_invite(t) && prepare_cancel_branch(t, branch, 0);
	/* mark branch as canceled */
	t->uac[branch].request.flags |= F_RB_CANCELED;
	t->uac[branch].request.flags |= F_RB_RELAYREPLY;
	if(is_local(t)) {
		reply_status = local_reply(t, FAKED_REPLY, branch, code, &cancel_data);
	} else {
		/* rely reply, but don't put on wait, we still need t
		 * to send the cancels */
		reply_status =
				relay_reply(t, FAKED_REPLY, branch, code, &cancel_data, 0);
	}
/* now when out-of-lock do the cancel I/O */
#ifdef CANCEL_REASON_SUPPORT
	if(do_cancel_branch)
		cancel_branch(t, branch, &cancel_data.reason, 0);
#else /* CANCEL_REASON_SUPPORT */
	if(do_cancel_branch)
		cancel_branch(t, branch, 0);
#endif /* CANCEL_REASON_SUPPORT */
	/* it's cleaned up on error; if no error occurred and transaction
	   completed regularly, I have to clean-up myself
	*/
	if(reply_status == RPS_COMPLETED)
		put_on_wait(t);
}
示例#2
0
/** 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;
	branch_bm_t mask;
	
	*cancel_bm=0;
	branches_no=t->nr_of_outgoings;
	mask=~skip_branches;
	membar_depends(); 
	for( i=0 ; i<branches_no ; i++ ) {
		*cancel_bm |= ((mask & (1<<i)) &&  prepare_cancel_branch(t, i, 1))<<i;
	}
}