diff options
author | Walter Doekes <walter+asterisk@wjd.nu> | 2013-08-09 20:29:09 +0000 |
---|---|---|
committer | Walter Doekes <walter+asterisk@wjd.nu> | 2013-08-09 20:29:09 +0000 |
commit | e744fa5f5bd323f68079600721bf1dffa55d3a53 (patch) | |
tree | 3ceedfc233c748a0992ac888b325ddcc0c5a2fa4 /main/autoservice.c | |
parent | b3813c8bc5cd14721ed3248aa37bbf29a9b2aba5 (diff) |
Don't leak frames when memory is full in autoservice_run.
Review: https://reviewboard.asterisk.org/r/2566/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@396505 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/autoservice.c')
-rw-r--r-- | main/autoservice.c | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/main/autoservice.c b/main/autoservice.c index 5b0c722ef..98f798b1a 100644 --- a/main/autoservice.c +++ b/main/autoservice.c @@ -144,34 +144,40 @@ static void *autoservice_run(void *ign) defer_frame = &hangup_frame; } else if (ast_is_deferrable_frame(f)) { defer_frame = f; + } else { + /* Can't defer. Discard and continue with next. */ + ast_frfree(f); + continue; } - if (defer_frame) { - for (i = 0; i < x; i++) { - struct ast_frame *dup_f; + for (i = 0; i < x; i++) { + struct ast_frame *dup_f; - if (mons[i] != chan) { - continue; - } + if (mons[i] != chan) { + continue; + } - if (defer_frame != f) { - if ((dup_f = ast_frdup(defer_frame))) { - AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list); - } - } else { - if ((dup_f = ast_frisolate(defer_frame))) { - if (dup_f != defer_frame) { - ast_frfree(defer_frame); - } - AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list); - } + if (!f) { /* defer_frame == &hangup_frame */ + if ((dup_f = ast_frdup(defer_frame))) { + AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list); + } + } else { + if ((dup_f = ast_frisolate(defer_frame))) { + AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list); + } + if (dup_f != defer_frame) { + ast_frfree(defer_frame); } - - break; } - } else if (f) { - ast_frfree(f); + + break; } + /* The ast_waitfor_n() call will only read frames from + * the channels' file descriptors. If ast_waitfor_n() + * returns non-NULL, then one of the channels in the + * mons array must have triggered the return. It's + * therefore impossible that we got here while (i >= x). + * If we did, we'd need to ast_frfree(f) if (f). */ } if (callid) { |