[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