mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 11:58:52 +00:00
ARI: Ensure announcer channels are destroyed.
Announcer channels were not being destroyed because the stasis_app_control structure that referenced them was not being destroyed. The control structure was not being destroyed because it was not being unlinked from its container. It was not being unlinked from its container because the after bridge callback for the announcer channel was not being run. The after bridge callback was not being run because the after bridge datastore was not being removed from the channel on destruction. The channel was not being destroyed because the hangup that used to destroy the channel was now only reducing the reference count to one. The reference count of the channel was only being reduced to one because the stasis_app_control structure was holding the final reference... The control structure used to not keep a reference to the channel, so that loop described above did not happen. The solution is to manually remove the control structure from its container when the playback on a bridge is complete. ASTERISK-26083 #close Reported by Joshua Colp Change-Id: I0ddc0f64484ea0016245800b409b567dfe85cfb4
This commit is contained in:
@@ -278,6 +278,7 @@ struct bridge_channel_control_thread_data {
|
||||
struct ast_channel *bridge_channel;
|
||||
struct stasis_app_control *control;
|
||||
struct stasis_forward *forward;
|
||||
char bridge_id[0];
|
||||
};
|
||||
|
||||
static void *bridge_channel_control_thread(void *data)
|
||||
@@ -287,6 +288,7 @@ static void *bridge_channel_control_thread(void *data)
|
||||
struct stasis_app_control *control = thread_data->control;
|
||||
struct stasis_forward *forward = thread_data->forward;
|
||||
ast_callid callid = ast_channel_callid(bridge_channel);
|
||||
char *bridge_id = ast_strdupa(thread_data->bridge_id);
|
||||
|
||||
if (callid) {
|
||||
ast_callid_threadassoc_add(callid);
|
||||
@@ -298,6 +300,7 @@ static void *bridge_channel_control_thread(void *data)
|
||||
stasis_app_control_execute_until_exhausted(bridge_channel, control);
|
||||
stasis_app_control_flush_queue(control);
|
||||
|
||||
stasis_app_bridge_playback_channel_remove(bridge_id, control);
|
||||
stasis_forward_cancel(forward);
|
||||
ao2_cleanup(control);
|
||||
ast_hangup(bridge_channel);
|
||||
@@ -466,8 +469,9 @@ static void ari_bridges_play_new(const char **args_media,
|
||||
}
|
||||
|
||||
/* Give play_channel and control reference to the thread data */
|
||||
thread_data = ast_calloc(1, sizeof(*thread_data));
|
||||
thread_data = ast_malloc(sizeof(*thread_data) + strlen(bridge->uniqueid) + 1);
|
||||
if (!thread_data) {
|
||||
stasis_app_bridge_playback_channel_remove((char *)bridge->uniqueid, control);
|
||||
ast_ari_response_alloc_failed(response);
|
||||
return;
|
||||
}
|
||||
@@ -475,8 +479,11 @@ static void ari_bridges_play_new(const char **args_media,
|
||||
thread_data->bridge_channel = play_channel;
|
||||
thread_data->control = control;
|
||||
thread_data->forward = channel_forward;
|
||||
/* Safe */
|
||||
strcpy(thread_data->bridge_id, bridge->uniqueid);
|
||||
|
||||
if (ast_pthread_create_detached(&threadid, NULL, bridge_channel_control_thread, thread_data)) {
|
||||
stasis_app_bridge_playback_channel_remove((char *)bridge->uniqueid, control);
|
||||
ast_ari_response_alloc_failed(response);
|
||||
ast_free(thread_data);
|
||||
return;
|
||||
|
Reference in New Issue
Block a user