[asterisk-commits] rmudgett: branch group/bridge_construction r382358 - in /team/group/bridge_co...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Mar 1 18:08:00 CST 2013
Author: rmudgett
Date: Fri Mar 1 18:07:57 2013
New Revision: 382358
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=382358
Log:
Fix race condition causing third channel in transition to three party bridges to wait in the wrong threading mode.
Modified:
team/group/bridge_construction/include/asterisk/bridging.h
team/group/bridge_construction/main/bridging.c
Modified: team/group/bridge_construction/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/include/asterisk/bridging.h?view=diff&rev=382358&r1=382357&r2=382358
==============================================================================
--- team/group/bridge_construction/include/asterisk/bridging.h (original)
+++ team/group/bridge_construction/include/asterisk/bridging.h Fri Mar 1 18:07:57 2013
@@ -144,6 +144,8 @@
pthread_t thread;
/*! Additional file descriptors to look at */
int fds[4];
+ /*! TRUE if the channel has been poked. */
+ unsigned int poked;
/*! TRUE if the channel is in a bridge. */
unsigned int in_bridge:1;
/*! TRUE if the channel just joined the bridge. */
Modified: team/group/bridge_construction/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/group/bridge_construction/main/bridging.c?view=diff&rev=382358&r1=382357&r2=382358
==============================================================================
--- team/group/bridge_construction/main/bridging.c (original)
+++ team/group/bridge_construction/main/bridging.c Fri Mar 1 18:07:57 2013
@@ -138,6 +138,7 @@
void ast_bridge_channel_poke(struct ast_bridge_channel *bridge_channel)
{
if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
+ bridge_channel->poked = 1;
pthread_kill(bridge_channel->thread, SIGURG);
ast_cond_signal(&bridge_channel->cond);
}
@@ -1287,27 +1288,31 @@
/* Wait for data to either come from the channel or us to be signaled */
ao2_lock(bridge_channel);
- if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
- ao2_unlock(bridge_channel);
- ao2_lock(bridge_channel->bridge);
+ if (bridge_channel->poked
+ || bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
} else if (bridge_channel->suspended) {
ast_debug(1, "Going into a multithreaded signal wait for bridge channel %p(%s) of bridge %p\n",
bridge_channel, ast_channel_name(bridge_channel->chan),
bridge_channel->bridge);
ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
- ao2_unlock(bridge_channel);
- ao2_lock(bridge_channel->bridge);
} else {
- ao2_unlock(bridge_channel);
ast_debug(10, "Going into a multithreaded waitfor for bridge channel %p(%s) of bridge %p\n",
bridge_channel, ast_channel_name(bridge_channel->chan),
bridge_channel->bridge);
+ ao2_unlock(bridge_channel);
chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, fds, nfds, NULL, &outfd, &ms);
ao2_lock(bridge_channel->bridge);
if (!bridge_channel->suspended) {
ast_bridge_handle_trip(bridge_channel->bridge, bridge_channel, chan, outfd);
}
- }
+ ao2_lock(bridge_channel);
+ bridge_channel->poked = 0;
+ ao2_unlock(bridge_channel);
+ return;
+ }
+ bridge_channel->poked = 0;
+ ao2_unlock(bridge_channel);
+ ao2_lock(bridge_channel->bridge);
}
/*! \brief Run in a singlethreaded model. Each joined channel yields itself to the main bridge thread. TODO: Improve */
@@ -1315,12 +1320,14 @@
{
ao2_unlock(bridge_channel->bridge);
ao2_lock(bridge_channel);
- if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
+ if (!bridge_channel->poked
+ && bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
ast_debug(1, "Going into a single threaded signal wait for bridge channel %p(%s) of bridge %p\n",
bridge_channel, ast_channel_name(bridge_channel->chan),
bridge_channel->bridge);
ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
}
+ bridge_channel->poked = 0;
ao2_unlock(bridge_channel);
ao2_lock(bridge_channel->bridge);
}
More information about the asterisk-commits
mailing list