[asterisk-commits] file: branch file/bridging r79130 - in /team/file/bridging: include/asterisk/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Aug 10 16:59:52 CDT 2007


Author: file
Date: Fri Aug 10 16:59:52 2007
New Revision: 79130

URL: http://svn.digium.com/view/asterisk?view=rev&rev=79130
Log:
Add ability for a bridge technology to replace the functionality of the bridge thread.

Modified:
    team/file/bridging/include/asterisk/bridging.h
    team/file/bridging/main/bridging.c

Modified: team/file/bridging/include/asterisk/bridging.h
URL: http://svn.digium.com/view/asterisk/team/file/bridging/include/asterisk/bridging.h?view=diff&rev=79130&r1=79129&r2=79130
==============================================================================
--- team/file/bridging/include/asterisk/bridging.h (original)
+++ team/file/bridging/include/asterisk/bridging.h Fri Aug 10 16:59:52 2007
@@ -75,6 +75,7 @@
 	int (*leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);                           /*! Callback for when a channel leaves a bridge */
 	int (*write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridged_channel, struct ast_frame *frame); /*! Callback for writing a frame to the bridge */
 	int (*fd)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, int fd);                      /*! Callback for when a file descriptor trips */
+	int (*thread)(struct ast_bridge *bridge);                                                                     /*! Callback for replacement thread function */
 	int formats;                                                                                                  /*! Formats this bridge technology can support */
 	int suspended:1;                                                                                              /*! Is this bridge technology suspended from use or not? */
 	AST_RWLIST_ENTRY(ast_bridge_technology) list;                                                                 /*! Linked list information */

Modified: team/file/bridging/main/bridging.c
URL: http://svn.digium.com/view/asterisk/team/file/bridging/main/bridging.c?view=diff&rev=79130&r1=79129&r2=79130
==============================================================================
--- team/file/bridging/main/bridging.c (original)
+++ team/file/bridging/main/bridging.c Fri Aug 10 16:59:52 2007
@@ -107,12 +107,84 @@
 	return current ? 0 : -1;
 }
 
+/*! \brief Generic thread loop */
+static int generic_thread_loop(struct ast_bridge *bridge)
+{
+	struct ast_channel *cs[128] = {NULL, }, *winner = NULL;
+	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 (ast_test_flag(&bridge->notify_flags, AST_BRIDGE_NOTIFY_REBUILD)) {
+			struct ast_bridge_channel *bridge_channel = NULL;
+			int i = 0;
+
+			AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, list) {
+				if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT && !bridge_channel->suspended)
+					cs[i++] = bridge_channel->chan;
+			}
+			
+			ast_debug(1, "Rebuild of bridge array on %p went from %d to %d.\n", bridge, count, i);
+			count = i;
+			
+			if (!count)
+				break;
+
+			ast_clear_flag(&bridge->notify_flags, AST_BRIDGE_NOTIFY_REBUILD);
+		} else if (count >= 2) {
+			int i = 0;
+			cs[127] = cs[0];
+			for (i = 0; i < (count-1); i++)
+				cs[i] = cs[i+1];
+			cs[count-1] = cs[127];
+		}
+
+		ast_mutex_unlock(&bridge->lock);
+		winner = ast_waitfor_n(cs, count, &to);
+		ast_mutex_lock(&bridge->lock);
+
+		/* If we had no winner, just continue on */
+		if (!winner)
+			continue;
+
+		AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, list) {
+			if (bridge_channel->chan == winner)
+				break;
+		}
+
+		/* Try to read a frame in, if this fails it means they hungup */
+		if (!(frame = 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);
+	}
+
+	return 0;
+}
+
 /*! \brief Bridge thread function */
 static void *bridge_thread(void *data)
 {
 	struct ast_bridge *bridge = data;
-	struct ast_channel *cs[128] = {NULL, }, *winner = NULL;
-	int to = -1, count = 0;
+	int res = 0;
 
 	ast_mutex_lock(&bridge->lock);
 
@@ -123,79 +195,8 @@
 		return NULL;
 	}
 
-	/* We now basically go into a giant loop handling bridged channels, handling notify flags, and general stuff like that */
-	while (bridge->thread != AST_PTHREADT_STOP) {
-		struct ast_frame *frame = NULL;
-
-		/* See if we need to rebuild the bridge array information */
-		if (ast_test_flag(&bridge->notify_flags, AST_BRIDGE_NOTIFY_REBUILD)) {
-			struct ast_bridge_channel *bridge_channel = NULL;
-			int i = 0;
-
-			/* Now we have to add each channel */
-			AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, list) {
-				if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT && !bridge_channel->suspended)
-					cs[i++] = bridge_channel->chan;
-			}
-
-			ast_debug(1, "Rebuild of bridge array on %p went from %d to %d.\n", bridge, count, i);
-			count = i;
-
-			/* If no bridge channels are in this bridge any longer discontinue the thread */
-			if (!count)
-				break;
-
-			/* All done. */
-			ast_clear_flag(&bridge->notify_flags, AST_BRIDGE_NOTIFY_REBUILD);
-		} else if (count >= 2) {
-			int i = 0;
-
-			/* Move channel priorities around */
-			cs[127] = cs[0];
-			for (i = 0; i < (count-1); i++)
-				cs[i] = cs[i+1];
-			cs[count-1] = cs[127];
-		}
-
-		/* Poll on the channels and file descriptors */
-		ast_mutex_unlock(&bridge->lock);
-		winner = ast_waitfor_n(cs, count, &to);
-		ast_mutex_lock(&bridge->lock);
-
-		/* If a winner was had... read it in */
-		if (winner) {
-			struct ast_bridge_channel *bridge_channel = NULL;
-
-			/* Look for the bridge channel structure */
-			AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, list) {
-				if (bridge_channel->chan == winner)
-					break;
-			}
-
-			/* Try to read in a frame, if this fails it means they hungup */
-			if (!(frame = 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, due 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);
-					}
-				}
-				/* Have ourselves rebuild next time */
-				ast_set_flag(&bridge->notify_flags, AST_BRIDGE_NOTIFY_REBUILD);
-			} 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);
-		}
-	}
+	/* Execute the appropriate thread function. If the technology does not provide one we use the generic one */
+	res = (bridge->technology->thread ? bridge->technology->thread(bridge) : generic_thread_loop(bridge));
 
 	ast_debug(1, "Ending bridge thread for %p\n", bridge);
 




More information about the asterisk-commits mailing list