summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2013-07-12 21:01:51 +0000
committerMark Michelson <mmichelson@digium.com>2013-07-12 21:01:51 +0000
commitd418e991eeabc1e7af078b02c6cf163a3121e65c (patch)
treed1b17c662e4f385fef198649b738267526e4ba77 /main
parentb700dc66415cce7e3f6503552897bf0167a7cb8e (diff)
Prevent potential race condition in multiparty basic bridges.
For more details about the race condition see the linked review at the bottom of this commit (closes issue ASTERISK-21882) Reported by Matt Jordan Review: https://reviewboard.asterisk.org/r/2663 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@394232 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/bridging_basic.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/main/bridging_basic.c b/main/bridging_basic.c
index c1c0045a6..844ff3cbd 100644
--- a/main/bridging_basic.c
+++ b/main/bridging_basic.c
@@ -99,9 +99,16 @@ struct ast_flags *ast_bridge_features_ds_get(struct ast_channel *chan)
*/
static int basic_hangup_hook(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
{
-/* BUGBUG Race condition. If all parties but one hangup at the same time, the bridge may not be dissolved on the remaining party. */
+ int bridge_count = 0;
+ struct ast_bridge_channel *iter;
+
ast_bridge_channel_lock_bridge(bridge_channel);
- if (2 < bridge_channel->bridge->num_channels) {
+ AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
+ if (iter != bridge_channel && iter->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
+ ++bridge_count;
+ }
+ }
+ if (2 <= bridge_count) {
/* Just allow this channel to leave the multi-party bridge. */
ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
}