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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sat Dec 1 19:19:59 CST 2007


Author: file
Date: Sat Dec  1 19:19:59 2007
New Revision: 90429

URL: http://svn.digium.com/view/asterisk?view=rev&rev=90429
Log:
Move the logic that handles when a channel/bridge needs servicing to a single function.

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=90429&r1=90428&r2=90429
==============================================================================
--- team/file/bridging/main/bridging.c (original)
+++ team/file/bridging/main/bridging.c Sat Dec  1 19:19:59 2007
@@ -107,6 +107,58 @@
 	return current ? 0 : -1;
 }
 
+/*! \brief Internal function to handle when a channel or bridge needs servicing */
+static void bridge_handle_trip(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_channel *chan, int outfd)
+{
+	/* If no bridge channel has been provided and the actual channel has been provided find it */
+	if (chan && !bridge_channel) {
+		AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, list) {
+			if (bridge_channel->chan == chan)
+				break;
+		}
+	}
+
+	/* If a bridge channel with actual channel is present read a frame and handle it */
+	if (chan && bridge_channel) {
+		struct ast_frame *frame = (bridge_channel->muted ? ast_read_noaudio(chan) : ast_read(chan));
+
+		/* This is pretty simple... see if they hung up */
+		if (!frame || (frame->frametype == AST_FRAME_CONTROL && frame->subclass == AST_CONTROL_HANGUP)) {
+			/* Signal the thread that is handling the bridged channel that it should be ended */
+			ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
+			/* If the bridge is set to dissolve hang up everyone */
+			if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE)) {
+				struct ast_bridge_channel *bridge_channel2 = NULL;
+				AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, list) {
+					if (bridge_channel2 != bridge_channel)
+						ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+				}
+			}
+		} else {
+			/* Simply write the frame out to the bridge technology */
+			bridge->technology->write(bridge, bridge_channel, frame);
+		}
+
+		if (frame)
+			ast_frfree(frame);
+		return;
+	}
+
+	/* If a file descriptor actually tripped pass it off to the bridge technology */
+	if (outfd > -1 && bridge->technology->fd) {
+		bridge->technology->fd(bridge, bridge_channel, outfd);
+		return;
+	}
+
+	/* If all else fails just poke the bridge */
+	if (bridge->technology->poke) {
+		bridge->technology->poke(bridge, bridge_channel);
+		return;
+	}
+
+	return;
+}
+
 /*! \brief Generic thread loop */
 static int generic_thread_loop(struct ast_bridge *bridge)
 {
@@ -114,9 +166,6 @@
 	int to = -1, count = 0;
 
 	while (bridge->thread != AST_PTHREADT_STOP) {
-		struct ast_frame *frame = NULL;
-		struct ast_bridge_channel *bridge_channel = NULL;
-
 		/* See if we need to rebuild the bridge array information */
 		if (bridge->rebuild) {
 			struct ast_bridge_channel *bridge_channel = NULL;
@@ -146,42 +195,7 @@
 		winner = ast_waitfor_n(cs, count, &to);
 		ast_mutex_lock(&bridge->lock);
 
-		/* If we had no winner just poke the bridge technology if possible */
-		if (!winner) {
-			if (bridge->technology->poke)
-				bridge->technology->poke(bridge, NULL);
-			continue;
-		}
-
-		AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, list) {
-			if (bridge_channel->chan == winner)
-				break;
-		}
-
-		/* Make sure we have a channel that is still present */
-		if (!bridge_channel)
-			continue;
-
-		/* Try to read a frame in, if this fails it means they hungup */
-		if (!(frame = (bridge_channel->muted ? ast_read_noaudio(winner) : ast_read(winner))) || (frame->frametype == AST_FRAME_CONTROL && frame->subclass == AST_CONTROL_HANGUP)) {
-			/* Switch the bridged channel state to end and signal it's thread */
-			ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
-			/* If the bridge is set to dissolve upon anyone hanging up, do so */
-			if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE)) {
-				struct ast_bridge_channel *bridge_channel2 = NULL;
-				AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, list) {
-					if (bridge_channel2 != bridge_channel)
-						ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
-				}
-			}
-		} else {
-			/* Write out the frame to the bridge technology */
-			bridge->technology->write(bridge, bridge_channel, frame);
-		}
-
-		/* If a frame exists free it */
-		if (frame)
-			ast_frfree(frame);
+		bridge_handle_trip(bridge, NULL, winner, -1);
 	}
 
 	return 0;
@@ -511,7 +525,7 @@
 /*! \brief Run in a multithreaded model. Each joined channel does writing/reading in their own thread. */
 static enum ast_bridge_channel_state bridge_channel_join_multithreaded(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
-	int fds[4] = {-1, }, outfd = -1, ms = -1, nfds = 0, i = 0;
+	int fds[4] = {-1, }, nfds = 0, i = 0;
 
 	/* Add any file descriptors to be watched if a callback function exists for them */
 	if (bridge->technology->fd) {
@@ -524,15 +538,9 @@
 	}
 
 	/* Go into a loop waiting for frames from the channel, or the associated file descriptors to trip */
-	for (;;) {
+	while (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
 		struct ast_channel *chan = NULL;
-
-		outfd = -1;
-		ms = -1;
-
-		/* Ensure this bridged channel is still up before and after we do our blocking operation */
-		if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT)
-			break;
+		int outfd = -1, ms = -1;
 
 		/* Wait for data on any of the file descriptors */
 		ast_mutex_unlock(&bridge->lock);
@@ -542,28 +550,7 @@
 			usleep(1);
 		ast_mutex_lock(&bridge->lock);
 
-		if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT)
-			break;
-
-		/* See if it was the channel that caused us to awaken */
-		if (chan) {
-			struct ast_frame *frame = NULL;
-			/* Try to read in a frame, if this fails it means they hungup */
-                        if (!(frame = (bridge_channel->muted ? ast_read_noaudio(chan) : ast_read(chan))) || (frame->frametype == AST_FRAME_CONTROL && frame->subclass == AST_CONTROL_HANGUP)) {
-                                /* Switch the bridged channel state to end, no need to signal it's thread... we are it! */
-				bridge_channel->state = AST_BRIDGE_CHANNEL_STATE_END;
-			} else if ((frame->frametype == AST_FRAME_DTMF_BEGIN || frame->frametype == AST_FRAME_DTMF_END) && bridge_channel->features) {
-                        } else {
-                                /* Write out the frame to the bridge technology */
-                                bridge->technology->write(bridge, bridge_channel, frame);
-                        }
-			if (frame)
-				ast_frfree(frame);
-		} else if (outfd > -1) {
-			bridge->technology->fd(bridge, bridge_channel, outfd);
-		} else if (bridge->technology->poke) {
-			bridge->technology->poke(bridge, bridge_channel);
-		}
+		bridge_handle_trip(bridge, bridge_channel, chan, outfd);
 	}
 
 	return bridge_channel->state;




More information about the asterisk-commits mailing list