[asterisk-bugs] [JIRA] (ASTERISK-26469) Infinite loop after a dual Redirect
Etienne Allovon (JIRA)
noreply at issues.asterisk.org
Fri Oct 14 09:18:01 CDT 2016
Etienne Allovon created ASTERISK-26469:
------------------------------------------
Summary: Infinite loop after a dual Redirect
Key: ASTERISK-26469
URL: https://issues.asterisk.org/jira/browse/ASTERISK-26469
Project: Asterisk
Issue Type: Bug
Security Level: None
Components: Bridges/bridge_simple
Affects Versions: 13.11.2
Environment: Debian 8.1
Reporter: Etienne Allovon
*Summary :*
Given I have two channels bridged together by asterisk.
Gvien I send an AMI commend Redirect (with channel and extra_channel set)
Then an asterisk thread may end up using 100% cpu. One of the channel thread is stuck in the while loop at the end of {{bridge_channel_internal_join()}} where it waits for the flag {{AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT}} to be cleared.
*More details :*
The problem occurs when sending an ami command to redirect two bridged channels to another extension (Redirect with channel and extra_channel set). During the process, one of the channel thread is stuck in the while loop at the end of {{bridge_channel_internal_join()}} where it waits for the flag {{AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT}} to be cleared:
{code}
/*
* Wait for any dual redirect to complete.
*
* Must be done while "still in the bridge" for ast_async_goto()
* to work right.
*/
while (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT)) {
sched_yield();
}
{code}
The other channel thread seems to complete successfully.
One possible source of the problem lies in {{bridge_channel_internal_pull()}} which clears the flag {{AST_FLAG_OUTGOING}} without locking the channel first:
{code}
/* If we are not going to be hung up after leaving a bridge, and we were an
* outgoing channel, clear the outgoing flag.
*/
if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING)
&& (ast_channel_is_leaving_bridge(bridge_channel->chan)
|| bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) {
ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan));
ast_clear_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING);
}
{code}
When in the manager thread, the {{action_redirect()}} clears the {{AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT}}:
{code}
/* Release the bridge wait. */
if (chan1_wait) {
ast_channel_lock(chan);
ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan);
}
if (chan2_wait) {
ast_channel_lock(chan2);
ast_clear_flag(ast_channel_flags(chan2), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT);
ast_channel_unlock(chan2);
}
{code}
So maybe the {{ast_clear_flag}} done inside the {{action_redirect()}} from the manager thread is overwritten by this call to {{ast_clear_flags}} in {{bridge_channel_internal_pull()}}
--
This message was sent by Atlassian JIRA
(v6.2#6252)
More information about the asterisk-bugs
mailing list