mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 20:04:50 +00:00
Merge "res_stasis: Fix crash on a hanging up channel."
This commit is contained in:
@@ -1371,6 +1371,9 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc,
|
|||||||
remove_stasis_end_published(chan);
|
remove_stasis_end_published(chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop any lingering silence generator */
|
||||||
|
control_silence_stop_now(control);
|
||||||
|
|
||||||
/* There's an off chance that app is ready for cleanup. Go ahead
|
/* There's an off chance that app is ready for cleanup. Go ahead
|
||||||
* and clean up, just in case
|
* and clean up, just in case
|
||||||
*/
|
*/
|
||||||
|
@@ -87,21 +87,19 @@ static void control_dtor(void *obj)
|
|||||||
{
|
{
|
||||||
struct stasis_app_control *control = obj;
|
struct stasis_app_control *control = obj;
|
||||||
|
|
||||||
|
ao2_cleanup(control->command_queue);
|
||||||
|
|
||||||
|
ast_channel_cleanup(control->channel);
|
||||||
|
ao2_cleanup(control->app);
|
||||||
|
|
||||||
|
ast_cond_destroy(&control->wait_cond);
|
||||||
AST_LIST_HEAD_DESTROY(&control->add_rules);
|
AST_LIST_HEAD_DESTROY(&control->add_rules);
|
||||||
AST_LIST_HEAD_DESTROY(&control->remove_rules);
|
AST_LIST_HEAD_DESTROY(&control->remove_rules);
|
||||||
|
|
||||||
/* We may have a lingering silence generator; free it */
|
|
||||||
ast_channel_stop_silence_generator(control->channel, control->silgen);
|
|
||||||
control->silgen = NULL;
|
|
||||||
|
|
||||||
ao2_cleanup(control->command_queue);
|
|
||||||
ast_cond_destroy(&control->wait_cond);
|
|
||||||
ao2_cleanup(control->app);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app)
|
struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app)
|
||||||
{
|
{
|
||||||
RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
|
struct stasis_app_control *control;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
control = ao2_alloc(sizeof(*control), control_dtor);
|
control = ao2_alloc(sizeof(*control), control_dtor);
|
||||||
@@ -109,28 +107,29 @@ struct stasis_app_control *control_create(struct ast_channel *channel, struct st
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
control->app = ao2_bump(app);
|
AST_LIST_HEAD_INIT(&control->add_rules);
|
||||||
|
AST_LIST_HEAD_INIT(&control->remove_rules);
|
||||||
|
|
||||||
res = ast_cond_init(&control->wait_cond, NULL);
|
res = ast_cond_init(&control->wait_cond, NULL);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
|
ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
ao2_ref(control, -1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
control->app = ao2_bump(app);
|
||||||
|
|
||||||
|
ast_channel_ref(channel);
|
||||||
|
control->channel = channel;
|
||||||
|
|
||||||
control->command_queue = ao2_container_alloc_list(
|
control->command_queue = ao2_container_alloc_list(
|
||||||
AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
|
AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
|
||||||
|
|
||||||
if (!control->command_queue) {
|
if (!control->command_queue) {
|
||||||
|
ao2_ref(control, -1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
control->channel = channel;
|
|
||||||
|
|
||||||
AST_LIST_HEAD_INIT(&control->add_rules);
|
|
||||||
AST_LIST_HEAD_INIT(&control->remove_rules);
|
|
||||||
|
|
||||||
ao2_ref(control, +1);
|
|
||||||
return control;
|
return control;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,8 +784,7 @@ void stasis_app_control_silence_start(struct stasis_app_control *control)
|
|||||||
stasis_app_send_command_async(control, app_control_silence_start, NULL, NULL);
|
stasis_app_send_command_async(control, app_control_silence_start, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int app_control_silence_stop(struct stasis_app_control *control,
|
void control_silence_stop_now(struct stasis_app_control *control)
|
||||||
struct ast_channel *chan, void *data)
|
|
||||||
{
|
{
|
||||||
if (control->silgen) {
|
if (control->silgen) {
|
||||||
ast_debug(3, "%s: Stopping silence generator\n",
|
ast_debug(3, "%s: Stopping silence generator\n",
|
||||||
@@ -795,7 +793,12 @@ static int app_control_silence_stop(struct stasis_app_control *control,
|
|||||||
control->channel, control->silgen);
|
control->channel, control->silgen);
|
||||||
control->silgen = NULL;
|
control->silgen = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int app_control_silence_stop(struct stasis_app_control *control,
|
||||||
|
struct ast_channel *chan, void *data)
|
||||||
|
{
|
||||||
|
control_silence_stop_now(control);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -108,5 +108,13 @@ int control_add_channel_to_bridge(
|
|||||||
struct stasis_app_control *control,
|
struct stasis_app_control *control,
|
||||||
struct ast_channel *chan, void *obj);
|
struct ast_channel *chan, void *obj);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Stop playing silence to a channel right now.
|
||||||
|
* \since 13.9.0
|
||||||
|
*
|
||||||
|
* \param control The control for chan
|
||||||
|
*/
|
||||||
|
void control_silence_stop_now(struct stasis_app_control *control);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _ASTERISK_RES_STASIS_CONTROL_H */
|
#endif /* _ASTERISK_RES_STASIS_CONTROL_H */
|
||||||
|
Reference in New Issue
Block a user