Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/asterisk/stasis_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,15 @@ int stasis_app_bridge_playback_channel_add(struct ast_bridge *bridge,
struct ast_channel *chan,
struct stasis_app_control *control);

/*!
* \brief Remove a bridge playback channel's control from the app controls list.
*
* \param bridge_id The unique ID of the bridge the playback channel is in.
* \param control The app control structure for the playback channel
*/
void stasis_app_bridge_playback_channel_control_remove(const char *bridge_id,
struct stasis_app_control *control);

/*!
* \brief remove channel from list of ARI playback channels for bridges.
*
Expand Down
23 changes: 16 additions & 7 deletions res/ari/resource_bridges.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,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];
char *bridge_id;
};

static void *bridge_channel_control_thread(void *data)
Expand All @@ -292,7 +292,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);
char *bridge_id = thread_data->bridge_id;

if (callid) {
ast_callid_threadassoc_add(callid);
Expand All @@ -304,7 +304,10 @@ 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);
if (bridge_id) {
stasis_app_bridge_playback_channel_control_remove(bridge_id, control);
ast_free(bridge_id);
}
stasis_forward_cancel(forward);
ao2_cleanup(control);
ast_hangup(bridge_channel);
Expand Down Expand Up @@ -532,7 +535,7 @@ static void ari_bridges_play_new(const char **args_media,
ast_bridge_queue_everyone_else(bridge, NULL, &prog);

/* Give play_channel and control reference to the thread data */
thread_data = ast_malloc(sizeof(*thread_data) + strlen(bridge->uniqueid) + 1);
thread_data = ast_calloc(1, sizeof(*thread_data));
if (!thread_data) {
stasis_app_bridge_playback_channel_remove((char *)bridge->uniqueid, control);
ast_ari_response_alloc_failed(response);
Expand All @@ -542,11 +545,17 @@ 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);
thread_data->bridge_id = ast_strdup(bridge->uniqueid);
if (!thread_data->bridge_id) {
stasis_app_bridge_playback_channel_remove((char *)bridge->uniqueid, control);
ast_ari_response_alloc_failed(response);
ast_free(thread_data);
return;
}

if (ast_pthread_create_detached(&threadid, NULL, bridge_channel_control_thread, thread_data)) {
stasis_app_bridge_playback_channel_remove((char *)bridge->uniqueid, control);
ast_free(thread_data->bridge_id);
ast_ari_response_alloc_failed(response);
ast_free(thread_data);
return;
Expand Down Expand Up @@ -653,7 +662,7 @@ static void ari_bridges_handle_play(
* in which case we'll revert to ari_bridges_play_new.
*/
if (ari_bridges_play_found(args_media, args_media_count, args_lang,
args_offset_ms, args_skipms, args_playback_id, response,bridge,
args_offset_ms, args_skipms, args_playback_id, response, bridge,
play_channel) == PLAY_FOUND_CHANNEL_UNAVAILABLE) {
continue;
}
Expand Down
9 changes: 8 additions & 1 deletion res/res_stasis.c
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,13 @@ static void remove_bridge_playback(char *bridge_id)
ast_free(bridge_id);
}

void stasis_app_bridge_playback_channel_control_remove(const char *bridge_id,
struct stasis_app_control *control)
{
ast_assert(!ast_strlen_zero(bridge_id));
ao2_unlink(app_controls, control);
}

static void playback_after_bridge_cb_failed(enum ast_bridge_after_cb_reason reason, void *data)
{
char *bridge_id = data;
Expand Down Expand Up @@ -777,7 +784,7 @@ void stasis_app_bridge_playback_channel_remove(char *bridge_id,
* called or is in progress. No need to unlink the control here since that has
* been done or is about to be done in the after bridge callback
*/
ao2_unlink(app_controls, control);
stasis_app_bridge_playback_channel_control_remove(bridge_id, control);
ao2_ref(wrapper, -1);
}
}
Expand Down
Loading