[asterisk-commits] rizzo: branch rizzo/astobj2 r47381 - /team/rizzo/astobj2/channels/chan_sip.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Nov 9 09:57:43 MST 2006


Author: rizzo
Date: Thu Nov  9 10:57:42 2006
New Revision: 47381

URL: http://svn.digium.com/view/asterisk?view=rev&rev=47381
Log:
add more pvt_unref(), and correct handling of references
around sip_scheddestroy() and related functions.


Modified:
    team/rizzo/astobj2/channels/chan_sip.c

Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=47381&r1=47380&r2=47381
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Thu Nov  9 10:57:42 2006
@@ -2078,7 +2078,9 @@
 	return AST_SUCCESS;
 }
 
-/*! \brief Kill a SIP dialog (called by scheduler) */
+/*! \brief Kill a SIP dialog (called by scheduler)
+ * We have a reference to the pvt, so we need to release it when done
+ */
 static int __sip_autodestruct(void *data)
 {
 	struct sip_pvt *p = data;
@@ -2106,10 +2108,11 @@
 	if (p->owner) {
 		ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
 		ast_queue_hangup(p->owner);
-	} else if (p->refer)
+	} else if (p->refer) {
 		transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
-	else 
-		sip_destroy(p);
+		pvt_unref(p);
+	} else 
+		sip_destroy(p);	/* absorb the reference */
 	return 0;
 }
 
@@ -2126,8 +2129,10 @@
 	if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
 		append_history(p, "SchedDestroy", "%d ms", ms);
 
-	if (p->autokillid > -1)
+	if (p->autokillid > -1)	/* cancel previous schedule, but keep the reference */
 		ast_sched_del(sched, p->autokillid);
+	else
+		pvt_ref(p);	/* create a new reference */
 	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
 }
 
@@ -2138,6 +2143,7 @@
 		ast_sched_del(sched, p->autokillid);
 		append_history(p, "CancelDestroy", "");
 		p->autokillid = -1;
+		pvt_unref(p);
 	}
 }
 
@@ -3443,7 +3449,7 @@
  * Part of PBX interface, called from ast_hangup */
 static int sip_hangup(struct ast_channel *ast)
 {
-	struct sip_pvt *p = ast->tech_pvt;
+	struct sip_pvt *p = ast->tech_pvt;	/* chan locked, don't need to grab a reference */
 	int needcancel = FALSE;
 	int needdestroy = 0;
 	struct ast_channel *oldowner = ast;
@@ -3457,9 +3463,7 @@
 	if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
 		if (option_debug >3)
 			ast_log(LOG_DEBUG, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
-		if (p->autokillid > -1)
-			sip_cancel_destroy(p);
-		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);	/* also cancels previous one if there */
 		ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Really hang up next time */
 		ast_clear_flag(&p->flags[0], SIP_NEEDDESTROY);
 		if (p->owner->tech_pvt)	/* i believe that's always */
@@ -8231,7 +8235,6 @@
 			transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
 		}
 
-		/* Schedule auto destroy in 32 seconds */
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		return AUTH_CHALLENGE_SENT;
 	} 
@@ -8242,7 +8245,6 @@
 	/* Challenge again, and again, and again */
 	transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
 	sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-
 	return AUTH_CHALLENGE_SENT;
 }
 
@@ -8276,9 +8278,7 @@
 	switch(state) {
 	case AST_EXTENSION_DEACTIVATED:	/* Retry after a while */
 	case AST_EXTENSION_REMOVED:	/* Extension is gone */
-		if (p->autokillid > -1)
-			sip_cancel_destroy(p);	/* Remove subscription expiry for renewals */
-		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);	/* Delete subscription in 32 secs */
+		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);	/* Delete subscription in 32 secs, possibly remove old sched. */
 		ast_verbose(VERBOSE_PREFIX_2 "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
 		p->stateid = -1;
 		p->subscribed = NONE;
@@ -13464,7 +13464,7 @@
 
 		if (p->refer->refer_call == p) {
 			ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
-			p->refer->refer_call = NULL;
+			p->refer->refer_call = pvt_unref(p->refer->refer_call);
 			transmit_response(p, "400 Bad request", req);	/* The best way to not not accept the transfer */
 			error = 1;
 		}
@@ -13893,6 +13893,7 @@
 		ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);	
 		transferer->refer->status = REFER_FAILED;
 		sip_pvt_unlock(targetcall_pvt);
+		pvt_unref(targetcall_pvt);
 		ast_channel_unlock(current->chan1);
 		ast_channel_unlock(target.chan1);
 		return -1;
@@ -13933,6 +13934,7 @@
 			ast_channel_unlock(targetcall_pvt->owner);
 		}
 	}
+	pvt_unref(targetcall_pvt);
 	return 1;
 }
 



More information about the asterisk-commits mailing list