[asterisk-commits] file: branch file/bridging r90734 - /team/file/bridging/main/bridging.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Dec 3 16:58:59 CST 2007


Author: file
Date: Mon Dec  3 16:58:59 2007
New Revision: 90734

URL: http://svn.digium.com/view/asterisk?view=rev&rev=90734
Log:
Add code for merging two branches together. This is not tested as of yet, I'm on the phone with Dwayne and do not wish to hang up or put him on hold.

Modified:
    team/file/bridging/main/bridging.c

Modified: team/file/bridging/main/bridging.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/main/bridging.c?view=diff&rev=90734&r1=90733&r2=90734
==============================================================================
--- team/file/bridging/main/bridging.c (original)
+++ team/file/bridging/main/bridging.c Mon Dec  3 16:58:59 2007
@@ -938,7 +938,83 @@
  */
 int ast_bridge_merge(struct ast_bridge *bridge0, struct ast_bridge *bridge1)
 {
-	return -1;
+	struct ast_bridge_channel *bridge_channel = NULL;
+
+	ast_mutex_lock(&bridge0->lock);
+
+	/* If the first bridge currently has 2 channels and is not capable of becoming a multi party bridge then they can not be merged */
+	if (bridge0->num == 2 && (!(bridge0->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) && !ast_test_flag(&bridge0->feature_flags, AST_BRIDGE_FLAG_SMART))) {
+		ast_debug(1, "Can't merge bridge %p into bridge %p, multimix is needed and is not available.\n", bridge1, bridge0);
+		ast_mutex_unlock(&bridge0->lock);
+		return -1;
+	}
+
+	ast_mutex_lock(&bridge1->lock);
+	
+	if ((bridge0->num+bridge1->num) > 2 && (!(bridge0->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX))) {
+		/* If smart bridging is not enabled we are not permitted to move to a multimix capable bridge technology */
+		if (!ast_test_flag(&bridge0->feature_flags, AST_BRIDGE_FLAG_SMART)) {
+			ast_debug(1, "Can't merge bridge %p into bridge %p, multimix is needed and is not available.\n", bridge1, bridge0);
+			ast_mutex_unlock(&bridge1->lock);
+			ast_mutex_unlock(&bridge0->lock);
+			return -1;
+		}
+	}
+
+	/* Try to perform the smart bridge operation on bridge0 to get it to change technologies */
+	if (smart_bridge_operation(bridge0, NULL, bridge0->num+bridge1->num)) {
+		ast_debug(1, "Failed to perform smart bridge operation on %p for bridge merging of %p\n", bridge0, bridge1);
+		ast_mutex_unlock(&bridge1->lock);
+		ast_mutex_unlock(&bridge0->lock);
+		return -1;
+	}
+
+	/* If bridge1 has a thread running we need to stop it so we have control of the channels */
+	if (bridge1->thread != AST_PTHREADT_NULL && bridge1->thread != AST_PTHREADT_STOP) {
+		pthread_t thread = bridge1->thread;
+
+		ast_debug(1, "Telling bridge thread on %p to stop so we can perform merge\n", bridge1);
+		bridge1->thread = AST_PTHREADT_STOP;
+		pthread_kill(thread, SIGURG);
+		ast_debug(1, "Giving up lock on bridge %p so thread stops\n", bridge1);
+		ast_mutex_unlock(&bridge1->lock);
+		pthread_join(thread, NULL);
+		ast_mutex_lock(&bridge1->lock);
+		ast_debug(1, "Reacquired lock on bridge %p, now performing merge to %p\n", bridge1, bridge0);
+	}
+
+	/* Move all channels from bridge1 to bridge0 */
+	while ((bridge_channel = AST_LIST_REMOVE_HEAD(&bridge1->channels, list))) {
+		/* First we decrement the channel count on bridge1 */
+		ast_atomic_fetchadd_int(&bridge1->num, -1);
+		/* Second we part them from bridge1 */
+		if (bridge1->technology->leave) {
+			ast_debug(1, "Giving bridge technology %s notification that %p is leaving bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
+			if (bridge1->technology->leave(bridge1, bridge_channel))
+				ast_debug(1, "Bridge technology %s failed to allow %p to leave bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
+		}
+		/* Third we add them to the list on bridge0 */
+		AST_LIST_INSERT_TAIL(&bridge0->channels, bridge_channel, list);
+		/* Fourth we increment the channel count on bridge 0 */
+		ast_atomic_fetchadd_int(&bridge0->num, +1);
+		/* And finally change the channel to point to this bridge */
+		bridge_channel->chan->bridge = bridge0;
+		/* Fifth we make them compatible with bridge0 */
+		bridge_make_compatible(bridge0, bridge_channel);
+		/* Sixth we join them to bridge0 */
+		if (bridge0->technology->join) {
+			ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
+			if (bridge0->technology->join(bridge0, bridge_channel))
+				ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
+		}
+	}
+
+	ast_debug(1, "Bridge %p has been merged into bridge %p\n", bridge1, bridge0);
+
+	ast_mutex_unlock(&bridge1->lock);
+	ast_mutex_unlock(&bridge0->lock);
+
+	return 0;
 }
 
 /*! \brief Suspend a bridge technology from consideration




More information about the asterisk-commits mailing list