[asterisk-commits] jrose: trunk r373608 - /trunk/res/res_agi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 25 09:53:48 CDT 2012


Author: jrose
Date: Tue Sep 25 09:53:42 2012
New Revision: 373608

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=373608
Log:
res_agi: async_agi responsiveness improvement on datastore problems

This patch changes get_agi_cmd so that the return can be checked
to differentiate between an empty list success and something that
triggered an error. This in turn allows launch_asyncagi to detect
these errors and break free from the command processing loop so
that the async agi can be ended more cleanly

(closes issue ASTERISK-20109)
Reported by: Jeremiah Gowdy
Patches: jgowdy-7-9-2012.diff uploaded by Jeremiah Gowdy (license 6358)
           (Modified by me to fix some logical issues and apply to trunk)
Review: https://reviewboard.asterisk.org/r/2117/

Modified:
    trunk/res/res_agi.c

Modified: trunk/res/res_agi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_agi.c?view=diff&rev=373608&r1=373607&r2=373608
==============================================================================
--- trunk/res/res_agi.c (original)
+++ trunk/res/res_agi.c Tue Sep 25 09:53:42 2012
@@ -1003,10 +1003,18 @@
 	.destroy = agi_destroy_commands_cb
 };
 
-static struct agi_cmd *get_agi_cmd(struct ast_channel *chan)
+/*!
+ * \brief Retrieve the list head to the requested channel's AGI datastore
+ * \param chan Channel datastore is requested for
+ * \param cmd Pointer to the struct pointer which will reference the head of the agi command list.
+ *
+ * \retval 0 if the datastore was valid and the list head was retrieved appropriately (even if it's
+ *           NULL and the list is empty)
+ * \retval -1 if the datastore could not be retrieved causing an error
+*/
+static int get_agi_cmd(struct ast_channel *chan, struct agi_cmd **cmd)
 {
 	struct ast_datastore *store;
-	struct agi_cmd *cmd;
 	AST_LIST_HEAD(, agi_cmd) *agi_commands;
 
 	ast_channel_lock(chan);
@@ -1015,13 +1023,14 @@
 	if (!store) {
 		ast_log(LOG_ERROR, "Huh? Async AGI datastore disappeared on Channel %s!\n",
 			ast_channel_name(chan));
-		return NULL;
+		*cmd = NULL;
+		return -1;
 	}
 	agi_commands = store->data;
 	AST_LIST_LOCK(agi_commands);
-	cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
+	*cmd = AST_LIST_REMOVE_HEAD(agi_commands, entry);
 	AST_LIST_UNLOCK(agi_commands);
-	return cmd;
+	return 0;
 }
 
 /* channel is locked when calling this one either from the CLI or manager thread */
@@ -1322,7 +1331,16 @@
 		 * Process as many commands as we can.  Commands are added via
 		 * the manager or the cli threads.
 		 */
-		while (!hungup && (cmd = get_agi_cmd(chan))) {
+		while (!hungup) {
+			res = get_agi_cmd(chan, &cmd);
+
+			if (res) {
+				returnstatus = AGI_RESULT_FAILURE;
+				goto async_agi_done;
+			} else if (!cmd) {
+				break;
+			}
+
 			/* OK, we have a command, let's call the command handler. */
 			cmd_status = agi_handle_command(chan, &async_agi, cmd->cmd_buffer, 0);
 




More information about the asterisk-commits mailing list