[asterisk-commits] rizzo: trunk r77650 - /trunk/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Jul 28 12:16:24 CDT 2007


Author: rizzo
Date: Sat Jul 28 12:16:24 2007
New Revision: 77650

URL: http://svn.digium.com/view/asterisk?view=rev&rev=77650
Log:
more dialog_ref()/dialog_unref() calls

Modified:
    trunk/channels/chan_sip.c

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=77650&r1=77649&r2=77650
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Sat Jul 28 12:16:24 2007
@@ -2386,7 +2386,11 @@
 		return AST_SUCCESS;
 }
 
-/*! \brief Kill a SIP dialog (called by scheduler) */
+/*! \brief Kill a SIP dialog (called only by the scheduler)
+ * The scheduler has a reference to this dialog when p->autokillid != -1,
+ * and we are called using that reference. So if the event is not
+ * rescheduled, we need to call dialog_unref().
+ */
 static int __sip_autodestruct(void *data)
 {
 	struct sip_pvt *p = data;
@@ -2410,15 +2414,18 @@
 	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);
+		dialog_unref(p);
 	} else if (p->refer) {
 		ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
 		transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
 		append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+		dialog_unref(p);
 	} else {
 		append_history(p, "AutoDestroy", "%s", p->callid);
 		ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
 		sip_destroy(p);		/* Go ahead and destroy dialog. All attempts to recover is done */
+		/* sip_destroy also absorbs the reference */
 	}
 	return 0;
 }
@@ -2433,21 +2440,23 @@
 	}
 	if (sip_debug_test_pvt(p))
 		ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
+	sip_cancel_destroy(p);
 	if (p->do_history)
 		append_history(p, "SchedDestroy", "%d ms", ms);
-
-	if (p->autokillid > -1)
-		ast_sched_del(sched, p->autokillid);
-	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
-}
-
-/*! \brief Cancel destruction of SIP dialog */
+	p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p));
+}
+
+/*! \brief Cancel destruction of SIP dialog.
+ * Be careful as this also absorbs the reference - if you call it
+ * from within the scheduler, this might be the last reference.
+ */
 static void sip_cancel_destroy(struct sip_pvt *p)
 {
 	if (p->autokillid > -1) {
 		ast_sched_del(sched, p->autokillid);
 		append_history(p, "CancelDestroy", "");
 		p->autokillid = -1;
+		dialog_unref(p);
 	}
 }
 
@@ -12179,6 +12188,7 @@
 		ast_cli(fd, "Sending NOTIFY of type '%s' to '%s'\n", argv[2], argv[i]);
 		transmit_sip_request(p, &req);
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+		dialog_unref(p);
 	}
 
 	return RESULT_SUCCESS;




More information about the asterisk-commits mailing list