From 81c43d92f665bd696cb7bfbcfbbfb978fd0857dd Mon Sep 17 00:00:00 2001 From: Wenpeng Song <wenpeng.song@iopsys.eu> Date: Fri, 8 Mar 2024 09:58:36 +0000 Subject: [PATCH] Workaround for reference count correction There is a remaining channel when ref>2 or Asterisk may crash when ref<2 in ast_hangup(). --- main/bridge_channel.c | 4 +--- main/channel.c | 11 +++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/main/bridge_channel.c b/main/bridge_channel.c index 56c81843ab..207d408bdd 100644 --- a/main/bridge_channel.c +++ b/main/bridge_channel.c @@ -2974,10 +2974,8 @@ int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel) ast_debug(1, "Channel %s simulating UNHOLD for bridge end.\n", ast_channel_name(bridge_channel->chan)); ast_indicate(bridge_channel->chan, AST_CONTROL_UNHOLD); - // leaving channel with Ref > 2 cause it is not destroyed during hangup - while (2 < ao2_ref(bridge_channel->chan, 0)) - ao2_ref(bridge_channel->chan, -1); } + ast_debug(3, "channel %s, Refs: %d\n", ast_channel_name(bridge_channel->chan),ao2_ref(bridge_channel->chan, 0)); /* Complete any partial DTMF digit before exiting the bridge. */ if (ast_channel_sending_dtmf_digit(bridge_channel->chan)) { diff --git a/main/channel.c b/main/channel.c index eabfe2f0f6..245337aed5 100644 --- a/main/channel.c +++ b/main/channel.c @@ -2548,6 +2548,17 @@ void ast_hangup(struct ast_channel *chan) ast_debug(1, "Channel %p '%s' hanging up. Refs: %d\n", chan, ast_channel_name(chan), ao2_ref(chan, 0)); + // leaving channel with Ref > 2 cause it is not destroyed during hangup, Ref < 2 cause crash during hangup + // race condition during REFER on chan_voicemngr_attended_call_transfer, + // Ref = 1 during the hangup when this ref decrease happened before the unref from chan_voicemngr_attended_call_transfer + if (2 != ao2_ref(chan, 0)){ + ast_log(LOG_NOTICE, "ref count mismatched during hangup\n"); + while (2 < ao2_ref(chan, 0)) + ao2_ref(chan, -1); + while (2 > ao2_ref(chan, 0)) // Add ref back in case of race condition happened. + ao2_ref(chan, +1); + ast_debug(3, "channel %s, Refs: %d\n", ast_channel_name(chan),ao2_ref(chan, 0)); + } ast_autoservice_stop(chan); -- GitLab