[asterisk-bugs] [JIRA] (ASTERISK-26469) Infinite loop after a dual Redirect

Jatin Jain (JIRA) noreply at issues.asterisk.org
Mon Jun 5 04:08:58 CDT 2017


    [ https://issues.asterisk.org/jira/browse/ASTERISK-26469?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=237294#comment-237294 ] 

Jatin Jain commented on ASTERISK-26469:
---------------------------------------

I have attached the gtack in which the threads were still stuck in while loop.

> 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