Fix memory issue that crept up with Russell's testing. It is *not* proper to free...
authorJoshua Colp <jcolp@digium.com>
Thu, 6 Sep 2007 22:34:44 +0000 (22:34 +0000)
committerJoshua Colp <jcolp@digium.com>
Thu, 6 Sep 2007 22:34:44 +0000 (22:34 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@81858 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/audiohook.c
main/channel.c

index cddfd10..d1dc6d0 100644 (file)
@@ -582,8 +582,6 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
                        /* Here's the scoop... middle frame is no longer of use to us */
                        ast_frfree(middle_frame);
                }
-               /* Yay let's rid ourselves of the start frame */
-               ast_frfree(start_frame);
        } else {
                /* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
                ast_frfree(middle_frame);
index 8e1f59b..83389a7 100644 (file)
@@ -2313,8 +2313,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
                                                chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
                                        ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
                                }
-                               if (chan->audiohooks)
+                               if (chan->audiohooks) {
+                                       struct ast_frame *old_frame = f;
                                        f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
+                                       if (old_frame != f)
+                                               ast_frfree(old_frame);
+                               }
                        } else {
                                struct timeval now = ast_tvnow();
                                if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
@@ -2336,8 +2340,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
                                        ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
                                        chan->dtmf_tv = now;
                                }
-                               if (chan->audiohooks)
+                               if (chan->audiohooks) {
+                                       struct ast_frame *old_frame = f;
                                        f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
+                                       if (old_frame != f)
+                                               ast_frfree(old_frame);
+                               }
                        }
                        break;
                case AST_FRAME_DTMF_BEGIN:
@@ -2399,8 +2407,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
                                        f->subclass = chan->emulate_dtmf_digit;
                                        f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
                                        chan->dtmf_tv = now;
-                                       if (chan->audiohooks)
+                                       if (chan->audiohooks) {
+                                               struct ast_frame *old_frame = f;
                                                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
+                                               if (old_frame != f)
+                                                       ast_frfree(old_frame);
+                                       }
                                        ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
                                } else {
                                        /* Drop voice frames while we're still in the middle of the digit */
@@ -2416,8 +2428,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
                                f = &ast_null_frame;
                        } else if ((f->frametype == AST_FRAME_VOICE)) {
                                /* Send frame to audiohooks if present */
-                               if (chan->audiohooks)
+                               if (chan->audiohooks) {
+                                       struct ast_frame *old_frame = f;
                                        f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
+                                       if (old_frame != f)
+                                               ast_frfree(old_frame);
+                               }
                                if (chan->monitor && chan->monitor->read_stream ) {
                                        /* XXX what does this do ? */
 #ifndef MONITOR_CONSTANT_DELAY
@@ -2707,7 +2723,7 @@ int ast_write_video(struct ast_channel *chan, struct ast_frame *fr)
 int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 {
        int res = -1;
-       struct ast_frame *f = NULL;
+       struct ast_frame *f = NULL, *f2 = NULL;
 
        /* Stop if we're a zombie or need a soft hangup */
        ast_channel_lock(chan);
@@ -2755,8 +2771,12 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
                        chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
                break;
        case AST_FRAME_DTMF_BEGIN:
-               if (chan->audiohooks)
+               if (chan->audiohooks) {
+                       struct ast_frame *old_frame = fr;
                        fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
+                       if (old_frame != fr)
+                               f = fr;
+               }
                send_dtmf_event(chan, "Sent", fr->subclass, "Yes", "No");
                ast_clear_flag(chan, AST_FLAG_BLOCKING);
                ast_channel_unlock(chan);
@@ -2765,8 +2785,12 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
                CHECK_BLOCKING(chan);
                break;
        case AST_FRAME_DTMF_END:
-               if (chan->audiohooks)
+               if (chan->audiohooks) {
+                       struct ast_frame *old_frame = fr;
                        fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
+                       if (old_frame != fr)
+                               f = fr;
+               }
                send_dtmf_event(chan, "Sent", fr->subclass, "No", "Yes");
                ast_clear_flag(chan, AST_FLAG_BLOCKING);
                ast_channel_unlock(chan);
@@ -2801,9 +2825,13 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
                        break;  /*! \todo XXX should return 0 maybe ? */
 
                /* If audiohooks are present, write the frame out */
-               if (chan->audiohooks)
+               if (chan->audiohooks) {
+                       struct ast_frame *old_frame = fr;
                        fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
-               
+                       if (old_frame != fr)
+                               f2 = fr;
+               }
+
                /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
                if (fr->subclass == chan->rawwriteformat)
                        f = fr;
@@ -2858,6 +2886,8 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 
        if (f && f != fr)
                ast_frfree(f);
+       if (f2)
+               ast_frfree(f2);
        ast_clear_flag(chan, AST_FLAG_BLOCKING);
        /* Consider a write failure to force a soft hangup */
        if (res < 0)