[asterisk-commits] file: trunk r81858 - in /trunk/main: audiohook.c channel.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Sep 6 17:34:45 CDT 2007


Author: file
Date: Thu Sep  6 17:34:44 2007
New Revision: 81858

URL: http://svn.digium.com/view/asterisk?view=rev&rev=81858
Log:
Fix memory issue that crept up with Russell's testing. It is *not* proper to free the frame we get in ast_write.

Modified:
    trunk/main/audiohook.c
    trunk/main/channel.c

Modified: trunk/main/audiohook.c
URL: http://svn.digium.com/view/asterisk/trunk/main/audiohook.c?view=diff&rev=81858&r1=81857&r2=81858
==============================================================================
--- trunk/main/audiohook.c (original)
+++ trunk/main/audiohook.c Thu Sep  6 17:34:44 2007
@@ -582,8 +582,6 @@
 			/* 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);

Modified: trunk/main/channel.c
URL: http://svn.digium.com/view/asterisk/trunk/main/channel.c?view=diff&rev=81858&r1=81857&r2=81858
==============================================================================
--- trunk/main/channel.c (original)
+++ trunk/main/channel.c Thu Sep  6 17:34:44 2007
@@ -2313,8 +2313,12 @@
 						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 @@
 					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 @@
 					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 @@
 				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(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 @@
 			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 @@
 		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 @@
 			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 @@
 
 	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)




More information about the asterisk-commits mailing list