[svn-commits] dvossel: branch dvossel/hd_confbridge r311501 - /team/dvossel/hd_confbridge/m...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Mar 22 11:16:46 CDT 2011


Author: dvossel
Date: Tue Mar 22 11:16:42 2011
New Revision: 311501

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=311501
Log:
Astobj2-ify ast_bridge_channel structure in bridging core

Modified:
    team/dvossel/hd_confbridge/main/bridging.c

Modified: team/dvossel/hd_confbridge/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/hd_confbridge/main/bridging.c?view=diff&rev=311501&r1=311500&r2=311501
==============================================================================
--- team/dvossel/hd_confbridge/main/bridging.c (original)
+++ team/dvossel/hd_confbridge/main/bridging.c Tue Mar 22 11:16:42 2011
@@ -123,9 +123,9 @@
 	/* Only poke the channel's thread if it is not us */
 	if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
 		pthread_kill(bridge_channel->thread, SIGURG);
-		ast_mutex_lock(&bridge_channel->lock);
+		ao2_lock(bridge_channel);
 		ast_cond_signal(&bridge_channel->cond);
-		ast_mutex_unlock(&bridge_channel->lock);
+		ao2_unlock(bridge_channel);
 	}
 
 	return;
@@ -697,9 +697,9 @@
 
 		/* Fourth we tell them to wake up so they become aware that they above has happened */
 		pthread_kill(bridge_channel2->thread, SIGURG);
-		ast_mutex_lock(&bridge_channel2->lock);
+		ao2_lock(bridge_channel2);
 		ast_cond_signal(&bridge_channel2->cond);
-		ast_mutex_unlock(&bridge_channel2->lock);
+		ao2_unlock(bridge_channel2);
 	}
 
 	/* Now that all the channels have been moved over we need to get rid of all the information the old technology may have left around */
@@ -740,10 +740,10 @@
 		ast_debug(10, "Going into a multithreaded waitfor for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
 		chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, fds, nfds, NULL, &outfd, &ms);
 	} else {
-		ast_mutex_lock(&bridge_channel->lock);
+		ao2_lock(bridge_channel);
 		ast_debug(10, "Going into a multithreaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
-		ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
-		ast_mutex_unlock(&bridge_channel->lock);
+		ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
+		ao2_unlock(bridge_channel);
 	}
 
 	ao2_lock(bridge_channel->bridge);
@@ -759,12 +759,12 @@
 static enum ast_bridge_channel_state bridge_channel_join_singlethreaded(struct ast_bridge_channel *bridge_channel)
 {
 	ao2_unlock(bridge_channel->bridge);
-	ast_mutex_lock(&bridge_channel->lock);
+	ao2_lock(bridge_channel);
 	if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
 		ast_debug(1, "Going into a single threaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
-		ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
-	}
-	ast_mutex_unlock(&bridge_channel->lock);
+		ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
+	}
+	ao2_unlock(bridge_channel);
 	ao2_lock(bridge_channel->bridge);
 
 	return bridge_channel->state;
@@ -925,7 +925,10 @@
 	if (bridge_channel->swap) {
 		struct ast_bridge_channel *bridge_channel2 = NULL;
 
-		/* If we are performing a swap operation we do not need to execute the smart bridge operation as the actual number of channels involved will not have changed, we just need to tell the other channel to leave */
+		/* If we are performing a swap operation we do not need
+		 * to execute the smart bridge operation as the actual number
+		 * of channels involved will not have changed, we just need to
+		 * tell the other channel to leave */
 		if ((bridge_channel2 = find_bridge_channel(bridge_channel->bridge, bridge_channel->swap))) {
 			ast_debug(1, "Swapping bridge channel %p out from bridge %p so bridge channel %p can slip in\n", bridge_channel2, bridge_channel->bridge, bridge_channel);
 			ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
@@ -1035,48 +1038,65 @@
 	return bridge_channel->state;
 }
 
+static void bridge_channel_destroy(void *obj)
+{
+	struct ast_bridge_channel *bridge_channel = obj;
+
+	if (bridge_channel->bridge) {
+		ao2_ref(bridge_channel->bridge, -1);
+		bridge_channel->bridge = NULL;
+	}
+	/* Destroy elements of the bridge channel structure and the bridge channel structure itself */
+	ast_cond_destroy(&bridge_channel->cond);
+}
+
+static struct ast_bridge_channel *bridge_channel_alloc(struct ast_bridge *bridge)
+{
+	struct ast_bridge_channel *bridge_channel = ao2_alloc(sizeof(struct ast_bridge_channel), bridge_channel_destroy);
+	if (!(bridge_channel)) {
+		return NULL;
+	}
+	ast_cond_init(&bridge_channel->cond, NULL);
+	if (bridge) {
+		bridge_channel->bridge = bridge;
+		ao2_ref(bridge_channel->bridge, +1);
+	}
+	return bridge_channel;
+}
+
 enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge,
 	struct ast_channel *chan,
 	struct ast_channel *swap,
 	struct ast_bridge_features *features,
 	struct ast_bridge_tech_optimizations *tech_args)
 {
-	struct ast_bridge_channel bridge_channel = {
-		.chan = chan,
-		.swap = swap,
-		.bridge = bridge,
-		.features = features,
-	};
-	enum ast_bridge_channel_state state;
-
+	struct ast_bridge_channel *bridge_channel = bridge_channel_alloc(bridge);
+	enum ast_bridge_channel_state state = AST_BRIDGE_CHANNEL_STATE_HANGUP;
+
+	if (!bridge_channel) {
+		return state;
+	}
 	if (tech_args) {
-		memcpy(&bridge_channel.tech_args, tech_args, sizeof(bridge_channel.tech_args));
-	}
+		memcpy(&bridge_channel->tech_args, tech_args, sizeof(bridge_channel->tech_args));
+	}
+
 	/* Initialize various other elements of the bridge channel structure that we can't do above */
-	ast_mutex_init(&bridge_channel.lock);
-	ast_cond_init(&bridge_channel.cond, NULL);
-
-	ao2_ref(bridge_channel.bridge, +1);
-
-	state = bridge_channel_join(&bridge_channel);
-
-	ao2_ref(bridge_channel.bridge, -1);
-
-	/* Destroy some elements of the bridge channel structure above */
-	ast_mutex_destroy(&bridge_channel.lock);
-	ast_cond_destroy(&bridge_channel.cond);
+	bridge_channel->chan = chan;
+	bridge_channel->swap = swap;
+	bridge_channel->features = features;
+
+	state = bridge_channel_join(bridge_channel);
+
+	/* Cleanup all the data in the bridge channel after it leaves the bridge. */
+	ao2_lock(bridge_channel);
+	bridge_channel->chan = NULL;
+	bridge_channel->swap = NULL;
+	bridge_channel->features = NULL;
+	ao2_unlock(bridge_channel);
+
+	ao2_ref(bridge_channel, -1);
 
 	return state;
-}
-
-static struct ast_bridge_channel *free_bridge_channel(struct ast_bridge_channel *bridge_channel)
-{
-	/* Destroy elements of the bridge channel structure and the bridge channel structure itself */
-	ast_mutex_destroy(&bridge_channel->lock);
-	ast_cond_destroy(&bridge_channel->cond);
-
-	ast_free(bridge_channel);
-	return NULL;
 }
 
 /*! \brief Thread responsible for imparted bridged channels */
@@ -1086,45 +1106,40 @@
 	enum ast_bridge_channel_state state;
 
 	state = bridge_channel_join(bridge_channel);
-
-	ao2_ref(bridge_channel->bridge, -1);
 
 	/* If no other thread is going to take the channel then hang it up, or else we would have to service it until something else came along */
 	if (state == AST_BRIDGE_CHANNEL_STATE_END || state == AST_BRIDGE_CHANNEL_STATE_HANGUP) {
 		ast_hangup(bridge_channel->chan);
 	}
 
-	free_bridge_channel(bridge_channel);
+	/* cleanup */
+	ao2_lock(bridge_channel);
+	bridge_channel->chan = NULL;
+	bridge_channel->swap = NULL;
+	bridge_channel->features = NULL;
+	ao2_unlock(bridge_channel);
+
+	ao2_ref(bridge_channel, -1);
 
 	return NULL;
 }
 
 int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features)
 {
-	struct ast_bridge_channel *bridge_channel = NULL;
-
+	struct ast_bridge_channel *bridge_channel = bridge_channel_alloc(bridge);
 	/* Try to allocate a structure for the bridge channel */
-	if (!(bridge_channel = ast_calloc(1, sizeof(*bridge_channel)))) {
+	if (!(bridge_channel)) {
 		return -1;
 	}
 
 	/* Setup various parameters */
 	bridge_channel->chan = chan;
 	bridge_channel->swap = swap;
-	bridge_channel->bridge = bridge;
 	bridge_channel->features = features;
-
-	/* Initialize our mutex lock and condition */
-	ast_mutex_init(&bridge_channel->lock);
-	ast_cond_init(&bridge_channel->cond, NULL);
-
-	/* Bump up the reference count on the bridge, it'll get decremented later */
-	ao2_ref(bridge, +1);
 
 	/* Actually create the thread that will handle the channel */
 	if (ast_pthread_create(&bridge_channel->thread, NULL, bridge_channel_thread, bridge_channel)) {
-		ao2_ref(bridge, -1);
-		free_bridge_channel(bridge_channel);
+		ao2_ref(bridge_channel, -1);
 		return -1;
 	}
 
@@ -1241,9 +1256,9 @@
 
 		/* Poke the bridge channel, this will cause it to wake up and execute the proper threading model for the new bridge it is in */
 		pthread_kill(bridge_channel->thread, SIGURG);
-		ast_mutex_lock(&bridge_channel->lock);
+		ao2_lock(bridge_channel);
 		ast_cond_signal(&bridge_channel->cond);
-		ast_mutex_unlock(&bridge_channel->lock);
+		ao2_unlock(bridge_channel);
 	}
 
 	ast_debug(1, "Merged channels from bridge %p into bridge %p\n", bridge1, bridge0);




More information about the svn-commits mailing list