From 9d3f3a4b0acc016c68be678681de8df45d571482 Mon Sep 17 00:00:00 2001 From: Robert Mordec <r.mordec@slican.pl> Date: Mon, 21 May 2018 14:24:51 +0200 Subject: [PATCH] app_confbridge: Bridge and announcers not removed if conference ends quickly If a conference is ended very quickly after it was created (i.e., the first user immediately hangs up) then the conference bridge and announcer channels are not removed. When a conference is created, the push_announcer() function is added to the playback queue task processor and the conference object reference is bumped. If a conference is ended while the push_announcer() function is still going then the ao2_cleanup(conference) at the end of push_announcer() will call the destructor function - destroy_conference_bridge(). The destroy_conference_bridge() function will then add the hangup_playback() task to the playback queue and will wait for it to end. Since it is already a current task of the playback queue it will wait forever. This patch makes the conference thread call push_announcer() directly. This way the conference object reference bump is not needed. Since the playback queue task processor is only used by the conference thread itself, there is no danger of trying to play announcements before the announcer is pushed to the bridge. ASTERISK-27870 #close Change-Id: I947a50fb121422d90fd1816d643a54d75185a477 --- apps/app_confbridge.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index 94a36327d3..1c6b4648e2 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -1457,25 +1457,19 @@ static int alloc_playback_chan(struct confbridge_conference *conference) /*! * \brief Push the announcer channel into the bridge * - * This runs in the playback queue taskprocessor. - * - * \param data A confbridge_conference + * \param conference Conference bridge to push the announcer to * \retval 0 Success * \retval -1 Failed to push the channel to the bridge */ -static int push_announcer(void *data) +static int push_announcer(struct confbridge_conference *conference) { - struct confbridge_conference *conference = data; - if (conf_announce_channel_push(conference->playback_chan)) { ast_hangup(conference->playback_chan); conference->playback_chan = NULL; - ao2_cleanup(conference); return -1; } ast_autoservice_start(conference->playback_chan); - ao2_cleanup(conference); return 0; } @@ -1588,7 +1582,7 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen return NULL; } - if (ast_taskprocessor_push(conference->playback_queue, push_announcer, ao2_bump(conference))) { + if (push_announcer(conference)) { ao2_unlink(conference_bridges, conference); ao2_ref(conference, -1); ao2_unlock(conference_bridges); -- GitLab