[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