[asterisk-commits] mmichelson: branch mmichelson/transfer r386431 - /team/mmichelson/transfer/main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 24 13:58:48 CDT 2013


Author: mmichelson
Date: Wed Apr 24 13:58:45 2013
New Revision: 386431

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386431
Log:
Only lock the bridge once, just to get the list of channels on it.

This also fixed a reference leak of the transferee channel.


Modified:
    team/mmichelson/transfer/main/bridging.c

Modified: team/mmichelson/transfer/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/main/bridging.c?view=diff&rev=386431&r1=386430&r2=386431
==============================================================================
--- team/mmichelson/transfer/main/bridging.c (original)
+++ team/mmichelson/transfer/main/bridging.c Wed Apr 24 13:58:45 2013
@@ -4295,25 +4295,10 @@
 	return AST_BRIDGE_TRANSFER_SUCCESS;
 }
 
-static enum ast_transfer_result queue_blind_transfer_bridge_action(struct ast_bridge *bridge,
-		struct ast_channel *transferer, const char *exten, const char *context)
-{
-	RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
-	RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
+static struct ast_channel *get_transferee(struct ao2_container *channels, struct ast_channel *transferer)
+{
 	struct ao2_iterator channel_iter;
-	struct blind_transfer_data blind_data;
 	struct ast_channel *transferee;
-
-	ast_channel_lock(transferer);
-	ast_copy_string(blind_data.transferer_name, ast_channel_name(transferer),
-			sizeof(blind_data.transferer_name));
-	ast_channel_unlock(transferer);
-
-	channels = ast_bridge_peers(bridge);
-
-	if (!channels) {
-		return AST_BRIDGE_TRANSFER_FAIL;
-	}
 
 	for (channel_iter = ao2_iterator_init(channels, 0);
 			(transferee = ao2_iterator_next(&channel_iter));
@@ -4322,7 +4307,27 @@
 			break;
 		}
 	}
+
 	ao2_iterator_destroy(&channel_iter);
+	return transferee;
+}
+
+static enum ast_transfer_result queue_blind_transfer_bridge_action(struct ao2_container *channels,
+		struct ast_channel *transferer, const char *exten, const char *context)
+{
+	RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
+	struct blind_transfer_data blind_data;
+
+	ast_channel_lock(transferer);
+	ast_copy_string(blind_data.transferer_name, ast_channel_name(transferer),
+			sizeof(blind_data.transferer_name));
+	ast_channel_unlock(transferer);
+
+	transferee = get_transferee(channels, transferer);
+	if (!transferee) {
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
 
 	ast_channel_lock(transferee);
 	ast_copy_string(blind_data.transferee_name, ast_channel_name(transferee),
@@ -4345,6 +4350,7 @@
 		const char *exten, const char *context, struct ast_framehook *hook)
 {
 	RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
+	RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
 	int do_bridge_transfer;
 	int transfer_prohibited;
 
@@ -4360,9 +4366,18 @@
 	ast_bridge_lock(bridge);
 	transfer_prohibited = ast_test_flag(&bridge->feature_flags,
 			AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
+	channels = ast_bridge_peers_nolock(bridge);
+	if (!channels) {
+		ast_bridge_unlock(bridge);
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
+	if (ao2_container_count(channels) <= 1) {
+		ast_bridge_unlock(bridge);
+		return AST_BRIDGE_TRANSFER_INVALID;
+	}
 	do_bridge_transfer = ast_test_flag(&bridge->feature_flags, 
 			AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY) ||
-			bridge->num_channels > 2;
+			ao2_container_count(channels) > 2;
 	ast_bridge_unlock(bridge);
 
 	if (transfer_prohibited) {
@@ -4373,7 +4388,7 @@
 		return local_channel_swap_transfer(transferer, bridge, exten, context);
 	}
 
-	return queue_blind_transfer_bridge_action(bridge, transferer, exten, context);
+	return queue_blind_transfer_bridge_action(channels, transferer, exten, context);
 }
 
 enum ast_transfer_result ast_bridge_attended_transfer(struct ast_channel *to_transferee,




More information about the asterisk-commits mailing list