[asterisk-commits] dvossel: trunk r344494 - in /trunk: ./ main/bridging.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Nov 10 15:56:19 CST 2011
Author: dvossel
Date: Thu Nov 10 15:56:16 2011
New Revision: 344494
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=344494
Log:
Merged revisions 344493 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/10
........
r344493 | dvossel | 2011-11-10 15:54:42 -0600 (Thu, 10 Nov 2011) | 12 lines
Fixes issue with ConfBridge participants hanging up during DTMF feature menu usage getting stuck in conference forever.
When a conference user enters the DTMF menu they are suspended from the
bridge while the channel is handed off to the DTMF feature code. If a
user entered this state and hungup, there existed a race condition where
the channel could not exit the conference because it was waiting on a
signal that would never arrive. This patch fixes that, because it would
stupid for me to talk about the problem and commit a patch for something else.
(closes issue ASTERISK-18829)
Reported by: zvision
........
Modified:
trunk/ (props changed)
trunk/main/bridging.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.
Modified: trunk/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/bridging.c?view=diff&rev=344494&r1=344493&r2=344494
==============================================================================
--- trunk/main/bridging.c (original)
+++ trunk/main/bridging.c Thu Nov 10 15:56:16 2011
@@ -739,12 +739,13 @@
ao2_unlock(bridge_channel->bridge);
+ ao2_lock(bridge_channel);
/* Wait for data to either come from the channel or us to be signalled */
if (!bridge_channel->suspended) {
+ ao2_unlock(bridge_channel);
ast_debug(10, "Going into a multithreaded waitfor for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, fds, nfds, NULL, &outfd, &ms);
} else {
- ao2_lock(bridge_channel);
ast_debug(10, "Going into a multithreaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
ao2_unlock(bridge_channel);
@@ -777,9 +778,10 @@
/*! \brief Internal function that suspends a channel from a bridge */
static void bridge_channel_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
{
+ ao2_lock(bridge_channel);
bridge_channel->suspended = 1;
-
bridge_array_remove(bridge, bridge_channel->chan);
+ ao2_unlock(bridge_channel);
if (bridge->technology->suspend) {
bridge->technology->suspend(bridge, bridge_channel);
@@ -791,13 +793,17 @@
/*! \brief Internal function that unsuspends a channel from a bridge */
static void bridge_channel_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
{
- bridge_channel->suspended =0;
-
+ ao2_lock(bridge_channel);
+ bridge_channel->suspended = 0;
bridge_array_add(bridge, bridge_channel->chan);
+ ast_cond_signal(&bridge_channel->cond);
+ ao2_unlock(bridge_channel);
if (bridge->technology->unsuspend) {
bridge->technology->unsuspend(bridge, bridge_channel);
}
+
+
return;
}
@@ -865,6 +871,12 @@
/* If a hook was actually matched execute it on this channel, otherwise stream up the DTMF to the other channels */
if (hook) {
hook->callback(bridge, bridge_channel, hook->hook_pvt);
+ /* If we are handing the channel off to an external hook for ownership,
+ * we are not guaranteed what kind of state it will come back in. If
+ * the channel hungup, we need to detect that here. */
+ if (bridge_channel->chan && ast_check_hangup_locked(bridge_channel->chan)) {
+ ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
+ }
} else {
ast_bridge_dtmf_stream(bridge, dtmf, bridge_channel->chan);
}
More information about the asterisk-commits
mailing list