[asterisk-bugs] [JIRA] (ASTERISK-26469) Infinite loop after a dual Redirect
Joshua Colp (JIRA)
noreply at issues.asterisk.org
Wed Dec 20 06:23:08 CST 2017
[ https://issues.asterisk.org/jira/browse/ASTERISK-26469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Joshua Colp updated ASTERISK-26469:
-----------------------------------
Assignee: (was: Mark Michelson)
> 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
> Attachments: 20161011-asterisk-bt-threads.txt, 20161011-asterisk-full.C-00006c9d.log, asterisk-26469-reproduce.py, gstack-infinite-loop.txt
>
>
> *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