summaryrefslogtreecommitdiff
path: root/main/autoservice.c
diff options
context:
space:
mode:
authorWalter Doekes <walter+asterisk@wjd.nu>2013-08-09 20:29:09 +0000
committerWalter Doekes <walter+asterisk@wjd.nu>2013-08-09 20:29:09 +0000
commite744fa5f5bd323f68079600721bf1dffa55d3a53 (patch)
tree3ceedfc233c748a0992ac888b325ddcc0c5a2fa4 /main/autoservice.c
parentb3813c8bc5cd14721ed3248aa37bbf29a9b2aba5 (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.c48
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) {