diff options
author | George Joseph <gjoseph@digium.com> | 2016-11-10 08:33:49 -0500 |
---|---|---|
committer | George Joseph <gjoseph@digium.com> | 2016-11-10 08:33:49 -0500 |
commit | 6bce938c2fcb60b7a77a0e997a6518860c0bfa39 (patch) | |
tree | ff98700292728dd43382244fdf88090604e4ebe0 /res/res_agi.c | |
parent | 28926d1c81540bbeb16802814d3f2e63c2347bd2 (diff) |
Revert "AGI: Only defer frames when in an interception routine."
This reverts commit 28926d1c81540bbeb16802814d3f2e63c2347bd2.
Multiple testsuite failures were detected after the fact.
Change-Id: I8d4f5ccbb421a351d616254844ae7e5a31053edb
Diffstat (limited to 'res/res_agi.c')
-rw-r--r-- | res/res_agi.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/res/res_agi.c b/res/res_agi.c index 5e047d4c3..06e8a03e2 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -4091,6 +4091,23 @@ static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, ch return AGI_RESULT_SUCCESS; } +AST_LIST_HEAD_NOLOCK(deferred_frames, ast_frame); + +static void queue_deferred_frames(struct deferred_frames *deferred_frames, + struct ast_channel *chan) +{ + struct ast_frame *f; + + if (!AST_LIST_EMPTY(deferred_frames)) { + ast_channel_lock(chan); + while ((f = AST_LIST_REMOVE_HEAD(deferred_frames, frame_list))) { + ast_queue_frame_head(chan, f); + ast_frfree(f); + } + ast_channel_unlock(chan); + } +} + static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi, int pid, int *status, int dead, int argc, char *argv[]) { struct ast_channel *c; @@ -4109,6 +4126,9 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi const char *sighup_str; const char *exit_on_hangup_str; int exit_on_hangup; + struct deferred_frames deferred_frames; + + AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames); ast_channel_lock(chan); sighup_str = pbx_builtin_getvar_helper(chan, "AGISIGHUP"); @@ -4170,8 +4190,20 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi /* Write, ignoring errors */ if (write(agi->audio, f->data.ptr, f->datalen) < 0) { } + ast_frfree(f); + } else if (ast_is_deferrable_frame(f)) { + struct ast_frame *dup_f; + + if ((dup_f = ast_frisolate(f))) { + AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list); + } + + if (dup_f != f) { + ast_frfree(f); + } + } else { + ast_frfree(f); } - ast_frfree(f); } } else if (outfd > -1) { size_t len = sizeof(buf); @@ -4219,6 +4251,8 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi buf[buflen - 1] = '\0'; } + queue_deferred_frames(&deferred_frames, chan); + if (agidebug) ast_verbose("<%s>AGI Rx << %s\n", ast_channel_name(chan), buf); cmd_status = agi_handle_command(chan, agi, buf, dead); @@ -4241,6 +4275,8 @@ static enum agi_result run_agi(struct ast_channel *chan, char *request, AGI *agi } } + queue_deferred_frames(&deferred_frames, chan); + if (agi->speech) { ast_speech_destroy(agi->speech); } |