[asterisk-commits] tilghman: trunk r122131 - in /trunk: ./ main/channel.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 12 10:14:38 CDT 2008


Author: tilghman
Date: Thu Jun 12 10:14:37 2008
New Revision: 122131

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

........
r122130 | tilghman | 2008-06-12 10:11:30 -0500 (Thu, 12 Jun 2008) | 4 lines

Occasionally, the alertpipe loses its nonblocking status, so detect and correct
that situation before it causes a deadlock.  (Reported and tested by ctooley
via #asterisk-dev)

........

Modified:
    trunk/   (props changed)
    trunk/main/channel.c

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

Modified: trunk/main/channel.c
URL: http://svn.digium.com/view/asterisk/trunk/main/channel.c?view=diff&rev=122131&r1=122130&r2=122131
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Jun 12 10:14:37 2008
@@ -824,6 +824,7 @@
 	if (needqueue) {
 		if (pipe(tmp->alertpipe)) {
 			ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
+alertpipe_failed:
 #ifdef HAVE_ZAPTEL
 			if (tmp->timingfd > -1)
 				close(tmp->timingfd);
@@ -834,9 +835,19 @@
 			return NULL;
 		} else {
 			flags = fcntl(tmp->alertpipe[0], F_GETFL);
-			fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
+			if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
+				ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
+				close(tmp->alertpipe[0]);
+				close(tmp->alertpipe[1]);
+				goto alertpipe_failed;
+			}
 			flags = fcntl(tmp->alertpipe[1], F_GETFL);
-			fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
+			if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
+				ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
+				close(tmp->alertpipe[0]);
+				close(tmp->alertpipe[1]);
+				goto alertpipe_failed;
+			}
 		}
 	} else	/* Make sure we've got it done right if they don't */
 		tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
@@ -2385,8 +2396,20 @@
 	
 	/* Read and ignore anything on the alertpipe, but read only
 	   one sizeof(blah) per frame that we send from it */
-	if (chan->alertpipe[0] > -1)
+	if (chan->alertpipe[0] > -1) {
+		int flags = fcntl(chan->alertpipe[0], F_GETFL);
+		/* For some odd reason, the alertpipe occasionally loses nonblocking status,
+		 * which immediately causes a deadlock scenario.  Detect and prevent this. */
+		if ((flags & O_NONBLOCK) == 0) {
+			ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
+			if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
+				ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
+				f = &ast_null_frame;
+				goto done;
+			}
+		}
 		read(chan->alertpipe[0], &blah, sizeof(blah));
+	}
 
 #ifdef HAVE_ZAPTEL
 	if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {




More information about the asterisk-commits mailing list