[asterisk-commits] russell: trunk r67022 - in /trunk: ./ channels/chan_iax2.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Mon Jun 4 08:50:46 MST 2007


Author: russell
Date: Mon Jun  4 10:50:46 2007
New Revision: 67022

URL: http://svn.digium.com/view/asterisk?view=rev&rev=67022
Log:
Merged revisions 67020 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r67020 | russell | 2007-06-04 10:47:40 -0500 (Mon, 04 Jun 2007) | 7 lines

Resolve a deadlock in chan_iax2.  When handling an implicit ACK to a frame that
was marked as the final transmission for a call, don't call iax2_destroy() for
that call while the global frame queue is still locked.  There is a very nice
explanation of the deadlock in the report.
(issue #9663, thorough report and patch from stevedavies, additional positive
 test reports from mihai and joff_oconnell)

........

Modified:
    trunk/   (props changed)
    trunk/channels/chan_iax2.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=67022&r1=67021&r2=67022
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Mon Jun  4 10:50:46 2007
@@ -6844,6 +6844,7 @@
 		    ((f.subclass != IAX_COMMAND_INVAL) ||
 		     (f.frametype != AST_FRAME_IAX))) {
 			unsigned char x;
+			int call_to_destroy;
 			/* XXX This code is not very efficient.  Surely there is a better way which still
 			       properly handles boundary conditions? XXX */
 			/* First we have to qualify that the ACKed value is within our window */
@@ -6857,20 +6858,23 @@
 					/* Ack the packet with the given timestamp */
 					if (option_debug && iaxdebug)
 						ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
+					call_to_destroy = 0;
 					AST_LIST_LOCK(&queue);
 					AST_LIST_TRAVERSE(&queue, cur, list) {
 						/* If it's our call, and our timestamp, mark -1 retries */
 						if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
 							cur->retries = -1;
 							/* Destroy call if this is the end */
-							if (cur->final) { 
-								if (iaxdebug && option_debug)
-									ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
-								iax2_destroy(fr->callno);
-							}
+							if (cur->final)
+								call_to_destroy = fr->callno;
 						}
 					}
 					AST_LIST_UNLOCK(&queue);
+					if (call_to_destroy) {
+						if (iaxdebug && option_debug)
+							ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
+						iax2_destroy(call_to_destroy);
+					}
 				}
 				/* Note how much we've received acknowledgement for */
 				if (iaxs[fr->callno])



More information about the asterisk-commits mailing list