mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-19 19:52:48 +00:00
app_dial.c: Moved channel lock to prevent deadlock
It's reproducible with pbx_lua, not regular dialplan. deadlock description: 1. asterisk locks a channel 2. calls function onedigit_goto 3. calls ast_goto_if_exists funciton 4. checks ast_exists_extension -> pbx_extension_helper 5. pbx_extension_helper calls pbx_find_extension 6. Then asterisk starts autoservice in a new thread 7. autoservice run tries to lock the channel again Because our channel is locked already, autoservice can't lock. Autoservice can't lock -> autoservice stop is waiting forever. onedigit_goto waits for autoservice stop. Resolves: https://github.com/asterisk/asterisk/issues/1335
This commit is contained in:
committed by
github-actions[bot]
parent
dce107234a
commit
b0421fc87c
@@ -1808,7 +1808,10 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
|
|||||||
if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
|
if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
|
||||||
const char *context;
|
const char *context;
|
||||||
ast_channel_lock(in);
|
ast_channel_lock(in);
|
||||||
context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
|
if ((context = pbx_builtin_getvar_helper(in, "EXITCONTEXT"))) {
|
||||||
|
context = ast_strdupa(context);
|
||||||
|
}
|
||||||
|
ast_channel_unlock(in);
|
||||||
if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
|
if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
|
||||||
ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
|
ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
|
||||||
*to_answer = 0;
|
*to_answer = 0;
|
||||||
@@ -1817,14 +1820,12 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
|
|||||||
pa->canceled = 1;
|
pa->canceled = 1;
|
||||||
publish_dial_end_event(in, out_chans, NULL, pa->status);
|
publish_dial_end_event(in, out_chans, NULL, pa->status);
|
||||||
ast_frfree(f);
|
ast_frfree(f);
|
||||||
ast_channel_unlock(in);
|
|
||||||
if (is_cc_recall) {
|
if (is_cc_recall) {
|
||||||
ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
|
ast_cc_completed(in, "CC completed, but the caller used DTMF to exit");
|
||||||
}
|
}
|
||||||
SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller pressed %c to end call\n",
|
SCOPE_EXIT_RTN_VALUE(NULL, "%s: Caller pressed %c to end call\n",
|
||||||
ast_channel_name(in), f->subclass.integer);
|
ast_channel_name(in), f->subclass.integer);
|
||||||
}
|
}
|
||||||
ast_channel_unlock(in);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
|
if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
|
||||||
|
Reference in New Issue
Block a user