]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 376208 via svnmerge from
authorAutomerge script <automerge@asterisk.org>
Tue, 13 Nov 2012 18:22:46 +0000 (18:22 +0000)
committerAutomerge script <automerge@asterisk.org>
Tue, 13 Nov 2012 18:22:46 +0000 (18:22 +0000)
file:///srv/subversion/repos/asterisk/branches/10

................
  r376208 | beagles | 2012-11-13 12:20:13 -0600 (Tue, 13 Nov 2012) | 14 lines

  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 376199 from http://svn.asterisk.org/svn/asterisk/branches/1.8
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10-digiumphones@376216 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/channel.c

index 9f367a19ac0145eb32f5b371174f6fa39930b092..8f71b05ed7ecc4ede3a32ad481b2e29281c5781f 100644 (file)
@@ -3169,7 +3169,11 @@ static int generator_force(const void *data)
 
        res = generate(chan, tmp, 0, ast_format_rate(&chan->writeformat) / 50);
 
-       chan->generatordata = tmp;
+       ast_channel_lock(chan);
+        if (chan->generator && generate == chan->generator->generate) {
+            chan->generatordata = tmp;
+        }
+       ast_channel_unlock(chan);
 
        if (res) {
                ast_debug(1, "Auto-deactivating generator\n");
@@ -8444,18 +8448,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 (!chan->generatordata) {
+               ast_debug(1, "Trying to stop silence generator when there is no "
+                   "generator on '%s'\n", chan->name);
+               ast_channel_unlock(chan);
+               return 0;
+       }
+       if (chan->generator != generator) {
+               ast_debug(1, "Trying to stop silence generator when it is not the current "
+                   "generator on '%s'\n", chan->name);
+               ast_channel_unlock(chan);
+               return 0;
+       }
+       if (chan->generator && chan->generator->release) {
+               chan->generator->release(chan, chan->generatordata);
+       }
+       chan->generatordata = NULL;
+       chan->generator = NULL;
+       ast_channel_set_fd(chan, AST_GENERATOR_FD, -1);
+       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
+       ast_settimeout(chan, 0, NULL, NULL);
+       ast_channel_unlock(chan);
 
-       ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
+       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", chan->name);
+               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);
 }