diff --git a/main/bridge_channel.c b/main/bridge_channel.c index 56c81843abbf4a4af1de5e65b2434756209c96bd..207d408bdd30a91f84767dbb5c75db47e604feae 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 eabfe2f0f6b1c0027b2044a0b9ca34065b008f10..245337aed59ff24622e7cbfb342b16bca385b391 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);