summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorBrent Eagles <beagles@digium.com>2012-11-15 14:35:01 +0000
committerBrent Eagles <beagles@digium.com>2012-11-15 14:35:01 +0000
commit6b07dd60ccf8a73635218b996c4f84b286ca447c (patch)
tree523c81ad1fff32e33a35b0d0af2972c7526967da /main
parent21a0dadac0ce968626be641d1395555884a1bfed (diff)
Patch to prevent stopping the active generator when it is not the silence
generator. This patch introduces an internal helper function to safely check whether the current generator is the one that is expected before deactivating it. The current externally accessible ast_channel_stop_generator() function has been modified to be implemented in terms of the new function. (closes issue ASTERISK-19918) Reported by: Eduardo Abad ........ Merged revisions 376217 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@376291 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/channel.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/main/channel.c b/main/channel.c
index 9998225f0..9edb0cc7f 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3144,7 +3144,11 @@ static int generator_force(const void *data)
res = generate(chan, tmp, 0, ast_format_rate(ast_channel_writeformat(chan)) / 50);
- ast_channel_generatordata_set(chan, tmp);
+ ast_channel_lock(chan);
+ if (ast_channel_generator(chan) && generate == ast_channel_generator(chan)->generate) {
+ ast_channel_generatordata_set(chan, tmp);
+ }
+ ast_channel_unlock(chan);
if (res) {
ast_debug(1, "Auto-deactivating generator\n");
@@ -8774,18 +8778,45 @@ struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_cha
return state;
}
-void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
+static int internal_deactivate_generator(struct ast_channel *chan, void* generator)
{
- if (!state)
- return;
+ ast_channel_lock(chan);
- ast_deactivate_generator(chan);
+ if (!ast_channel_generatordata(chan)) {
+ ast_debug(1, "Trying to stop silence generator when there is no "
+ "generator on '%s'\n", ast_channel_name(chan));
+ ast_channel_unlock(chan);
+ return 0;
+ }
+ if (ast_channel_generator(chan) != generator) {
+ ast_debug(1, "Trying to stop silence generator when it is not the current "
+ "generator on '%s'\n", ast_channel_name(chan));
+ ast_channel_unlock(chan);
+ return 0;
+ }
+ if (ast_channel_generator(chan) && ast_channel_generator(chan)->release) {
+ ast_channel_generator(chan)->release(chan, ast_channel_generatordata(chan));
+ }
+ ast_channel_generatordata_set(chan, NULL);
+ ast_channel_generator_set(chan, NULL);
+ ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
+ ast_clear_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT);
+ ast_settimeout(chan, 0, NULL, NULL);
+ ast_channel_unlock(chan);
- ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan));
+ return 1;
+}
- if (ast_set_write_format(chan, &state->old_write_format) < 0)
- ast_log(LOG_ERROR, "Could not return write format to its original state\n");
+void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
+{
+ if (!state)
+ return;
+ if (internal_deactivate_generator(chan, &silence_generator)) {
+ ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan));
+ if (ast_set_write_format(chan, &state->old_write_format) < 0)
+ ast_log(LOG_ERROR, "Could not return write format to its original state\n");
+ }
ast_free(state);
}