[asterisk-commits] diruggles: branch 1.6.0 r232811 - /branches/1.6.0/apps/app_externalivr.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Dec 3 08:48:02 CST 2009


Author: diruggles
Date: Thu Dec  3 08:47:57 2009
New Revision: 232811

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=232811
Log:
Merged revisions 232587 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r232587 | diruggles | 2009-12-02 17:17:22 -0500 (Wed, 02 Dec 2009) | 12 lines
  
  Prevent double closing of FDs by EIVR
  
  This caused a problem when asterisk was under heavy load and running both AGI and EIVR applications.
  EIVR would close an FD at which point it would be considered freed and be used by a new AGI instance
  the second close would then close the FD now in use by AGI.
  
  (closes issue #16305)
  Reported by: diLLec
  Tested by: thedavidfactor, diLLec
  
  Review: https://reviewboard.asterisk.org/r/436/
........

Modified:
    branches/1.6.0/apps/app_externalivr.c

Modified: branches/1.6.0/apps/app_externalivr.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.0/apps/app_externalivr.c?view=diff&rev=232811&r1=232810&r2=232811
==============================================================================
--- branches/1.6.0/apps/app_externalivr.c (original)
+++ branches/1.6.0/apps/app_externalivr.c Thu Dec  3 08:47:57 2009
@@ -93,7 +93,7 @@
 };
 
 static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u, 
-              int eivr_events_fd, int eivr_commands_fd, int eivr_errors_fd, 
+              int *eivr_events_fd, int *eivr_commands_fd, int *eivr_errors_fd, 
               const char *args);
 
 static void send_eivr_event(FILE *handle, const char event, const char *data,
@@ -297,9 +297,9 @@
 static int app_exec(struct ast_channel *chan, void *data)
 {
 	struct playlist_entry *entry;
-	int child_stdin[2] = { 0,0 };
-	int child_stdout[2] = { 0,0 };
-	int child_stderr[2] = { 0,0 };
+	int child_stdin[2] = { -1, -1 };
+	int child_stdout[2] = { -1, -1 };
+	int child_stderr[2] = { -1, -1 };
 	int res = -1;
 	int gen_active = 0;
 	int pid;
@@ -389,44 +389,44 @@
 		/* parent process */
 
 		close(child_stdin[0]);
-		child_stdin[0] = 0;
+		child_stdin[0] = -1;
 		close(child_stdout[1]);
-		child_stdout[1] = 0;
+		child_stdout[1] = -1;
 		close(child_stderr[1]);
-		child_stderr[1] = 0;
-		res = eivr_comm(chan, u, child_stdin[1], child_stdout[0], child_stderr[0], comma_delim_argbuf);
-
-		exit:
-		if (gen_active)
-			ast_deactivate_generator(chan);
-
-		if (child_stdin[0])
-			close(child_stdin[0]);
-
-		if (child_stdin[1])
-			close(child_stdin[1]);
-
-		if (child_stdout[0])
-			close(child_stdout[0]);
-
-		if (child_stdout[1])
-			close(child_stdout[1]);
-
-		if (child_stderr[0])
-			close(child_stderr[0]);
-
-		if (child_stderr[1])
-			close(child_stderr[1]);
-
-		while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
-			ast_free(entry);
-
-		return res;
-	}
+		child_stderr[1] = -1;
+		res = eivr_comm(chan, u, &child_stdin[1], &child_stdout[0], &child_stderr[0], comma_delim_argbuf);
+	}
+
+	exit:
+	if (gen_active) {
+		ast_deactivate_generator(chan);
+	}
+	if (child_stdin[0] > -1) {
+		close(child_stdin[0]);
+	}
+	if (child_stdin[1] > -1) {
+		close(child_stdin[1]);
+	}
+	if (child_stdout[0] > -1) {
+		close(child_stdout[0]);
+	}
+	if (child_stdout[1] > -1) {
+		close(child_stdout[1]);
+	}
+	if (child_stderr[0] > -1) {
+		close(child_stderr[0]);
+	}
+	if (child_stderr[1] > -1) {
+		close(child_stderr[1]);
+	}
+	while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list))) {
+		ast_free(entry);
+	}
+	return res;
 }
 
 static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u, 
- 				int eivr_events_fd, int eivr_commands_fd, int eivr_errors_fd, 
+ 				int *eivr_events_fd, int *eivr_commands_fd, int *eivr_errors_fd, 
  				const char *args)
 {
 	struct playlist_entry *entry;
@@ -434,7 +434,7 @@
 	int ms;
  	int exception;
  	int ready_fd;
- 	int waitfds[2] = { eivr_commands_fd, eivr_errors_fd };
+ 	int waitfds[2] = { *eivr_commands_fd, (eivr_errors_fd) ? *eivr_errors_fd : -1 };
  	struct ast_channel *rchan;
  	char *command;
  	int res = -1;
@@ -444,16 +444,16 @@
  	FILE *eivr_errors = NULL;
  	FILE *eivr_events = NULL;
  
- 	if (!(eivr_events = fdopen(eivr_events_fd, "w"))) {
+ 	if (!(eivr_events = fdopen(*eivr_events_fd, "w"))) {
  		ast_chan_log(LOG_WARNING, chan, "Could not open stream to send events\n");
  		goto exit;
  	}
- 	if (!(eivr_commands = fdopen(eivr_commands_fd, "r"))) {
+ 	if (!(eivr_commands = fdopen(*eivr_commands_fd, "r"))) {
  		ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive commands\n");
  		goto exit;
  	}
- 	if(eivr_errors_fd) {  /*if opening a socket connection, error stream will not be used*/
- 		if (!(eivr_errors = fdopen(eivr_errors_fd, "r"))) {
+ 	if (eivr_errors_fd) {  /*if opening a socket connection, error stream will not be used*/
+ 		if (!(eivr_errors = fdopen(*eivr_errors_fd, "r"))) {
  			ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive errors\n");
  			goto exit;
  		}
@@ -486,7 +486,7 @@
  		errno = 0;
  		exception = 0;
  
- 		rchan = ast_waitfor_nandfds(&chan, 1, waitfds, (eivr_errors_fd == 0) ? 1 : 2, &exception, &ready_fd, &ms);
+ 		rchan = ast_waitfor_nandfds(&chan, 1, waitfds, (eivr_errors_fd) ? 2 : 1, &exception, &ready_fd, &ms);
  
  		if (!AST_LIST_EMPTY(&u->finishlist)) {
  			AST_LIST_LOCK(&u->finishlist);
@@ -528,10 +528,10 @@
  				break;
  			}
  			ast_frfree(f);
- 		} else if (ready_fd == eivr_commands_fd) {
+ 		} else if (ready_fd == *eivr_commands_fd) {
  			char input[1024];
  
- 			if (exception || (dup2(eivr_commands_fd, test_available_fd) == -1) || feof(eivr_commands)) {
+ 			if (exception || (dup2(*eivr_commands_fd, test_available_fd) == -1) || feof(eivr_commands)) {
  				ast_chan_log(LOG_WARNING, chan, "Child process went away\n");
  				res = -1;
   				break;
@@ -618,7 +618,7 @@
  				else
  					ast_chan_log(LOG_WARNING, chan, "Unknown option requested '%s'\n", &input[2]);
  			}
- 		} else if (eivr_errors_fd && ready_fd == eivr_errors_fd) {
+ 		} else if (eivr_errors_fd && (ready_fd == *eivr_errors_fd)) {
  			char input[1024];
   
  			if (exception || feof(eivr_errors)) {
@@ -638,26 +638,25 @@
  			break;
  		}
  	}
-  
- 
-exit:
- 
+
+	exit:
 	if (test_available_fd > -1) {
 		close(test_available_fd);
 	}
-
-	if (eivr_events)
+	if (eivr_events) {
  		fclose(eivr_events);
- 
- 	if (eivr_commands)
+ 		*eivr_events_fd = -1;
+	}
+ 	if (eivr_commands) {
 		fclose(eivr_commands);
-
- 	if (eivr_errors)
+		*eivr_commands_fd = -1;
+	}
+ 	if (eivr_errors) {
  		fclose(eivr_errors);
-  
-  	return res;
- 
-  }
+  		*eivr_errors_fd = -1;
+	}
+	return res;
+ }
 
 static int unload_module(void)
 {




More information about the asterisk-commits mailing list