[asterisk-bugs] [JIRA] (ASTERISK-23988) BridgeWait: channel entering into holding bridge that is being destroyed fails to successfully join the newly created holding bridge
Matt Jordan (JIRA)
noreply at issues.asterisk.org
Wed Jul 2 17:22:58 CDT 2014
Matt Jordan created ASTERISK-23988:
--------------------------------------
Summary: BridgeWait: channel entering into holding bridge that is being destroyed fails to successfully join the newly created holding bridge
Key: ASTERISK-23988
URL: https://issues.asterisk.org/jira/browse/ASTERISK-23988
Project: Asterisk
Issue Type: Bug
Security Level: None
Components: Applications/app_bridgewait, Core/Bridging
Affects Versions: 12.3.2
Reporter: Matt Jordan
Holding bridges created by {{BridgeWait}} are a bit interesting: each named holding bridge can be shared by multiple participants. This creates an interesting race condition.
When the last channel leaves a bridge created by {{BridgeWait}}, we have to destroy the bridge. However, in some cases, a channel may be trying to enter the named holding bridge at the same time. Because {{BridgeWait}} cannot hold onto a reference to the bridge (as otherwise the bridge would never get disposed of), there is a case where a channel will attempt to join a holding bridge that just got destroyed.
The code handles this case: when this occurs, {{ast_bridge_join}} will fail. If {{ast_bridge_join}} fails, we attempt again - the attempt in and of itself will cause a new named holding bridge to be created, and from the perspective of the user, the join succeeds.
{code}
for (;;) {
RAII_VAR(struct wait_bridge_wrapper *, bridge_wrapper, get_wait_bridge_wrapper(bridge_name), wait_wrapper_removal);
if (!bridge_wrapper) {
ast_log(LOG_WARNING, "Failed to find or create waiting bridge '%s' for '%s'.\n", bridge_name, ast_channel_name(chan));
bridge_join_failed = 1;
break;
}
ast_verb(3, "%s is entering waiting bridge %s:%s\n", ast_channel_name(chan), bridge_name, bridge_wrapper->bridge->uniqueid);
if (ast_bridge_join(bridge_wrapper->bridge, chan, NULL, &chan_features, NULL, 0)) {
/* It's possible for a holding bridge to vanish out from under us since we can't lock it.
* Unlink the wrapper and then loop if the bridge we try to enter is dissolved. */
ast_verb(3, "Waiting bridge '%s:%s' is no longer joinable. Creating new bridge and trying again.\n",
bridge_name, bridge_wrapper->bridge->uniqueid);
ao2_unlink(wait_bridge_wrappers, bridge_wrapper);
continue;
}
break;
}
{code}
Unfortunately, this doesn't quite work. When the {{ast_bridge_join}} fails, we do create a new holding bridge, and we do attempt to put the channel into it. Unfortunately, the channel immediately bounces out of it:
{noformat}
-- Executing [s at hold:1] BridgeWait("PJSIP/103-00000017", "holding_lot") in new stack
-- PJSIP/103-00000017 is entering waiting bridge holding_lot:7b69b650-22d7-4ed0-83bf-d7b00acd23ba
-- Waiting bridge 'holding_lot:7b69b650-22d7-4ed0-83bf-d7b00acd23ba' is no longer joinable. Creating new bridge and trying again.
-- PJSIP/103-00000017 is entering waiting bridge holding_lot:24828e7f-ff78-4aa4-93d4-cee8cd4eced9
-- Channel PJSIP/103-00000017 joined 'holding_bridge' base-bridge <24828e7f-ff78-4aa4-93d4-cee8cd4eced9>
-- Started music on hold, class 'default', on channel 'PJSIP/103-00000017'
-- Stopped music on hold on PJSIP/103-00000017
-- Channel PJSIP/103-00000017 left 'holding_bridge' base-bridge <24828e7f-ff78-4aa4-93d4-cee8cd4eced9>
{noformat}
For some reason, we're immediately entering and bouncing right back out of the newly created holding bridge. When the race condition isn't hit, the channel joins just fine.
--
This message was sent by Atlassian JIRA
(v6.2#6252)
More information about the asterisk-bugs
mailing list