diff options
author | George Joseph <gjoseph@digium.com> | 2016-11-10 08:41:43 -0500 |
---|---|---|
committer | George Joseph <gjoseph@digium.com> | 2016-11-10 08:41:43 -0500 |
commit | 6be5d8de0da7e804544507f70382425af9a07b3f (patch) | |
tree | 3387769353a178428f01ae7d69719cdd85aae121 /res | |
parent | 5c10091f3d1430c6fc04015226f8c3e3aa9d8282 (diff) |
Revert "AGI: Only defer frames when in an interception routine."
This reverts commit 5c10091f3d1430c6fc04015226f8c3e3aa9d8282.
Multiple testsuite failures were detected after the fact.
Change-Id: I397a841acc17ae230c512449cd6bed89d2ef3b73
Diffstat (limited to 'res')
-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 969c62dd0..06df75293 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -4093,6 +4093,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; @@ -4111,6 +4128,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"); @@ -4172,8 +4192,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); @@ -4221,6 +4253,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); @@ -4243,6 +4277,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); } |