[asterisk-commits] rmudgett: branch 1.8 r398379 - /branches/1.8/channels/chan_iax2.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 5 12:07:47 CDT 2013


Author: rmudgett
Date: Thu Sep  5 12:07:44 2013
New Revision: 398379

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=398379
Log:
chan_iax2: Fix bridgecallno deadlock avoidance.

* Fix bridgecallno deadlock avoidance.  When doing deadlock avoidance, you
need to retest the status of values for each loop to see if you still need
the lock for bridgecallno.

* As a safety check, after acquiring the bridgecallno lock you should
check if iaxs[bridgecallno] is NULL just like the current callno checks.

* Move setting thread->iostate to IAX_IOSTATE_IDLE to after processing any
deferred frames to ensure that the iostate is IDLE when it is placed back
into the idle list.  defer_full_frame() tries to ensure
iax2_process_thread() wakes up to process the frame.

Modified:
    branches/1.8/channels/chan_iax2.c

Modified: branches/1.8/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_iax2.c?view=diff&rev=398379&r1=398378&r2=398379
==============================================================================
--- branches/1.8/channels/chan_iax2.c (original)
+++ branches/1.8/channels/chan_iax2.c Thu Sep  5 12:07:44 2013
@@ -806,7 +806,7 @@
 	/*! Status of knowledge of peer ADSI capability */
 	int peeradsicpe;
 
-	/*! Who we are bridged to */
+	/*! Callno of native bridge peer. (Valid if nonzero) */
 	unsigned short bridgecallno;
 
 	int pingid;			/*!< Transmit PING request */
@@ -11369,13 +11369,13 @@
 				}
 				break;
 			case IAX_COMMAND_TXREJ:
-				if (iaxs[fr->callno]->bridgecallno) {
-					while (ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
-						DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
-					}
-					if (!iaxs[fr->callno]) {
-						break;
-					}
+				while (iaxs[fr->callno]
+					&& iaxs[fr->callno]->bridgecallno
+					&& ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
+					DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
+				}
+				if (!iaxs[fr->callno]) {
+					break;
 				}
 
 				iaxs[fr->callno]->transferring = TRANSFER_NONE;
@@ -11386,20 +11386,21 @@
 					break;
 				}
 
-				if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
+				if (iaxs[iaxs[fr->callno]->bridgecallno]
+					&& iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
 					iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
 					send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
 				}
 				ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
 				break;
 			case IAX_COMMAND_TXREADY:
-				if (iaxs[fr->callno]->bridgecallno) {
-					while (ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
-						DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
-					}
-					if (!iaxs[fr->callno]) {
-						break;
-					}
+				while (iaxs[fr->callno]
+					&& iaxs[fr->callno]->bridgecallno
+					&& ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
+					DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
+				}
+				if (!iaxs[fr->callno]) {
+					break;
 				}
 
 				if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
@@ -11418,8 +11419,9 @@
 					break;
 				}
 
-				if (!(iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) &&
-				    !(iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
+				if (!iaxs[iaxs[fr->callno]->bridgecallno]
+					|| (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY
+						&& iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
 					ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
 					break;
 				}
@@ -11789,11 +11791,10 @@
 			break;
 		}
 
-		if (thread->iostate == IAX_IOSTATE_IDLE)
-			continue;
-
 		/* See what we need to do */
 		switch (thread->iostate) {
+		case IAX_IOSTATE_IDLE:
+			continue;
 		case IAX_IOSTATE_READY:
 			thread->actions++;
 			thread->iostate = IAX_IOSTATE_PROCESSING;
@@ -11806,14 +11807,10 @@
 #ifdef SCHED_MULTITHREADED
 			thread->schedfunc(thread->scheddata);
 #endif		
+			break;
 		default:
 			break;
 		}
-		time(&thread->checktime);
-		thread->iostate = IAX_IOSTATE_IDLE;
-#ifdef DEBUG_SCHED_MULTITHREAD
-		thread->curfunc[0]='\0';
-#endif		
 
 		/* The network thread added us to the active_thread list when we were given
 		 * frames to process, Now that we are done, we must remove ourselves from
@@ -11824,6 +11821,12 @@
 
 		/* Make sure another frame didn't sneak in there after we thought we were done. */
 		handle_deferred_full_frames(thread);
+
+		time(&thread->checktime);
+		thread->iostate = IAX_IOSTATE_IDLE;
+#ifdef DEBUG_SCHED_MULTITHREAD
+		thread->curfunc[0]='\0';
+#endif
 	}
 
 	/*!




More information about the asterisk-commits mailing list