[asterisk-commits] russell: branch 1.4 r91783 - /branches/1.4/apps/app_dial.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Dec 7 10:38:49 CST 2007


Author: russell
Date: Fri Dec  7 10:38:48 2007
New Revision: 91783

URL: http://svn.digium.com/view/asterisk?view=rev&rev=91783
Log:
* Add channel locking around datastore operations that expet the channel
  to be locked.
* Document why we don't record Local channels in the dialed interfaces list.
* Remove the dialed variable as it isn't needed.
* Restructure some code for clarity and coding guidelines stuff

Modified:
    branches/1.4/apps/app_dial.c

Modified: branches/1.4/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/apps/app_dial.c?view=diff&rev=91783&r1=91782&r2=91783
==============================================================================
--- branches/1.4/apps/app_dial.c (original)
+++ branches/1.4/apps/app_dial.c Fri Dec  7 10:38:48 2007
@@ -1103,7 +1103,6 @@
 		char *interface = ast_strdupa(number);
 		char *tech = strsep(&number, "/");
 		/* find if we already dialed this interface */
-		int dialed = 0;
 		struct ast_dialed_interface *di;
 		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
 		num_dialed++;
@@ -1124,49 +1123,67 @@
 		}
 		ast_copy_string(numsubst, number, sizeof(numsubst));
 		/* Request the peer */
-		if (!(datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL))) {
-			if(!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
+
+		ast_channel_lock(chan);
+		datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
+		ast_channel_unlock(chan);
+
+		if (datastore)
+			dialed_interfaces = datastore->data;
+		else {
+			if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
 				ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n"); 
 				free(tmp);
 				goto out;
 			}
-			else {
-				datastore->inheritance = DATASTORE_INHERIT_FOREVER;
-				if((dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
-					datastore->data = dialed_interfaces;
-					AST_LIST_HEAD_INIT(dialed_interfaces);
-					ast_channel_datastore_add(chan, datastore);
-				} else {
-					free(tmp);
-					goto out;
-				}
-			}
-		} else 
-			dialed_interfaces = datastore->data;
+
+			datastore->inheritance = DATASTORE_INHERIT_FOREVER;
+
+			if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
+				free(tmp);
+				goto out;
+			}
+
+			datastore->data = dialed_interfaces;
+			AST_LIST_HEAD_INIT(dialed_interfaces);
+
+			ast_channel_lock(chan);
+			ast_channel_datastore_add(chan, datastore);
+			ast_channel_unlock(chan);
+		}
+
 		AST_LIST_LOCK(dialed_interfaces);
 		AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
-			/* XXX case sensitive??? */
-			if(!strcasecmp(di->interface, interface)) {
-				dialed = 1;
+			if (!strcasecmp(di->interface, interface)) {
+				ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n", 
+					di->interface);
 				break;
 			}
 		}
-		if(!dialed && strcasecmp(tech, "Local")) {
-			if(!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
+		AST_LIST_UNLOCK(dialed_interfaces);
+
+		if (di) {
+			fulldial++;
+			free(tmp);
+			continue;
+		}
+
+		/* It is always ok to dial a Local interface.  We only keep track of
+		 * which "real" interfaces have been dialed.  The Local channel will
+		 * inherit this list so that if it ends up dialing a real interface,
+		 * it won't call one that has already been called. */
+		if (strcasecmp(tech, "Local")) {
+			if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
 				AST_LIST_UNLOCK(dialed_interfaces);
 				free(tmp);
 				goto out;
 			}
 			strcpy(di->interface, interface);
+
+			AST_LIST_LOCK(dialed_interfaces);
 			AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
-		} else if (dialed) {
-			ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n", di->interface);
 			AST_LIST_UNLOCK(dialed_interfaces);
-			fulldial++;
-			free(tmp);
-			continue;
-		}
-		AST_LIST_UNLOCK(dialed_interfaces);
+		}
 
 		tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
 		if (!tmp->chan) {




More information about the asterisk-commits mailing list