mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +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
9a366d2424
commit
186ef1a657
@@ -295,23 +295,23 @@ int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *reason_strings[] = {
|
||||
[AST_BRIDGE_AFTER_CB_REASON_DESTROY] = "Channel destroyed (hungup)",
|
||||
[AST_BRIDGE_AFTER_CB_REASON_REPLACED] = "Callback was replaced",
|
||||
[AST_BRIDGE_AFTER_CB_REASON_MASQUERADE] = "Channel masqueraded",
|
||||
[AST_BRIDGE_AFTER_CB_REASON_DEPART] = "Channel was departed from bridge",
|
||||
[AST_BRIDGE_AFTER_CB_REASON_REMOVED] = "Callback was removed",
|
||||
};
|
||||
|
||||
const char *ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason)
|
||||
{
|
||||
if (reason < AST_BRIDGE_AFTER_CB_REASON_DESTROY
|
||||
|| AST_BRIDGE_AFTER_CB_REASON_REMOVED < reason
|
||||
|| !reason_strings[reason]) {
|
||||
return "Unknown";
|
||||
switch (reason) {
|
||||
case AST_BRIDGE_AFTER_CB_REASON_DESTROY:
|
||||
return "Channel destroyed (hungup)";
|
||||
case AST_BRIDGE_AFTER_CB_REASON_REPLACED:
|
||||
return "Callback was replaced";
|
||||
case AST_BRIDGE_AFTER_CB_REASON_MASQUERADE:
|
||||
return "Channel masqueraded";
|
||||
case AST_BRIDGE_AFTER_CB_REASON_DEPART:
|
||||
return "Channel was departed from bridge";
|
||||
case AST_BRIDGE_AFTER_CB_REASON_REMOVED:
|
||||
return "Callback was removed";
|
||||
case AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED:
|
||||
return "Channel failed joining the bridge";
|
||||
}
|
||||
|
||||
return reason_strings[reason];
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
struct after_bridge_goto_ds {
|
||||
|
Reference in New Issue
Block a user