diff options
author | Joshua Colp <jcolp@digium.com> | 2016-03-31 08:16:15 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2016-03-31 08:16:15 -0500 |
commit | cb9b7f6b1befa30dd3d59e7b9423dfbb8adb568e (patch) | |
tree | 21d392fefe80e99cb4cac50f4b26462b3d752071 /res | |
parent | 2b5dfe668a61cf5eb02e693a39b9c82089a35412 (diff) | |
parent | a179aba65e117afb6480d8396e92df2e5d2d4628 (diff) |
Merge "res_stasis: Fix crash on a hanging up channel." into 13
Diffstat (limited to 'res')
-rw-r--r-- | res/res_stasis.c | 3 | ||||
-rw-r--r-- | res/stasis/control.c | 39 | ||||
-rw-r--r-- | res/stasis/control.h | 8 |
3 files changed, 32 insertions, 18 deletions
diff --git a/res/res_stasis.c b/res/res_stasis.c index 629955ed9..5dabc7f73 100644 --- a/res/res_stasis.c +++ b/res/res_stasis.c @@ -1371,6 +1371,9 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc, 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 * and clean up, just in case */ diff --git a/res/stasis/control.c b/res/stasis/control.c index ebb7e0194..00385a09f 100644 --- a/res/stasis/control.c +++ b/res/stasis/control.c @@ -87,21 +87,19 @@ static void control_dtor(void *obj) { struct stasis_app_control *control = obj; - AST_LIST_HEAD_DESTROY(&control->add_rules); - AST_LIST_HEAD_DESTROY(&control->remove_rules); + ao2_cleanup(control->command_queue); - /* We may have a lingering silence generator; free it */ - ast_channel_stop_silence_generator(control->channel, control->silgen); - control->silgen = NULL; + ast_channel_cleanup(control->channel); + ao2_cleanup(control->app); - ao2_cleanup(control->command_queue); ast_cond_destroy(&control->wait_cond); - ao2_cleanup(control->app); + AST_LIST_HEAD_DESTROY(&control->add_rules); + AST_LIST_HEAD_DESTROY(&control->remove_rules); } 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; 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; } - 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); if (res != 0) { ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n", strerror(errno)); + ao2_ref(control, -1); return NULL; } + control->app = ao2_bump(app); + + ast_channel_ref(channel); + control->channel = channel; + control->command_queue = ao2_container_alloc_list( AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL); - if (!control->command_queue) { + ao2_ref(control, -1); 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; } @@ -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); } -static int app_control_silence_stop(struct stasis_app_control *control, - struct ast_channel *chan, void *data) +void control_silence_stop_now(struct stasis_app_control *control) { if (control->silgen) { 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->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; } diff --git a/res/stasis/control.h b/res/stasis/control.h index a139f82e4..d053a35f7 100644 --- a/res/stasis/control.h +++ b/res/stasis/control.h @@ -108,5 +108,13 @@ int control_add_channel_to_bridge( struct stasis_app_control *control, 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 */ |