mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-18 18:58:22 +00:00
stasis/control: Fix possible deadlock with swap channel
If an error occurs during a bridge impart it's possible that the "bridge_after" callback might try to run before control_swap_channel_in_bridge has been signalled to continue. Since control_swap_channel_in_bridge is holding the control lock and the callback needs it, a deadlock will occur. * control_swap_channel_in_bridge now only holds the control lock while it's actually modifying the control structure and releases it while the bridge impart is running. * bridge_after_cb is now tolerant of impart failures. Change-Id: Ifd239aa93955b3eb475521f61e284fcb0da2c3b3
This commit is contained in:
committed by
Richard Mudgett
parent
2857a3334a
commit
94091c7b96
@@ -1758,12 +1758,13 @@ join_exit:;
|
||||
static void *bridge_channel_depart_thread(void *data)
|
||||
{
|
||||
struct ast_bridge_channel *bridge_channel = data;
|
||||
int res = 0;
|
||||
|
||||
if (bridge_channel->callid) {
|
||||
ast_callid_threadassoc_add(bridge_channel->callid);
|
||||
}
|
||||
|
||||
bridge_channel_internal_join(bridge_channel);
|
||||
res = bridge_channel_internal_join(bridge_channel);
|
||||
|
||||
/*
|
||||
* cleanup
|
||||
@@ -1775,7 +1776,8 @@ static void *bridge_channel_depart_thread(void *data)
|
||||
ast_bridge_features_destroy(bridge_channel->features);
|
||||
bridge_channel->features = NULL;
|
||||
|
||||
ast_bridge_discard_after_callback(bridge_channel->chan, AST_BRIDGE_AFTER_CB_REASON_DEPART);
|
||||
ast_bridge_discard_after_callback(bridge_channel->chan,
|
||||
res ? AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED : AST_BRIDGE_AFTER_CB_REASON_DEPART);
|
||||
/* If join failed there will be impart threads waiting. */
|
||||
bridge_channel_impart_signal(bridge_channel->chan);
|
||||
ast_bridge_discard_after_goto(bridge_channel->chan);
|
||||
|
Reference in New Issue
Block a user