[asterisk-commits] dvossel: tag 1.4.31-rc2 r260062 - in /tags/1.4.31-rc2: channels/ include/aste...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 29 11:06:44 CDT 2010


Author: dvossel
Date: Thu Apr 29 11:06:41 2010
New Revision: 260062

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=260062
Log:
bug fixes for RC

(closes issue 0017052)
Reported by: dvossel
Tested by: dvossel

(closes issue 0016196)
Reported by: atis

(closes issue 0017052)
Reported by: dvossel
Tested by: dvossel


Modified:
    tags/1.4.31-rc2/channels/chan_local.c
    tags/1.4.31-rc2/include/asterisk/audiohook.h
    tags/1.4.31-rc2/main/audiohook.c
    tags/1.4.31-rc2/main/channel.c

Modified: tags/1.4.31-rc2/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/tags/1.4.31-rc2/channels/chan_local.c?view=diff&rev=260062&r1=260061&r2=260062
==============================================================================
--- tags/1.4.31-rc2/channels/chan_local.c (original)
+++ tags/1.4.31-rc2/channels/chan_local.c Thu Apr 29 11:06:41 2010
@@ -543,12 +543,12 @@
 			/* Deadlock avoidance */
 			while (p->owner && ast_channel_trylock(p->owner)) {
 				ast_mutex_unlock(&p->lock);
-				if (ast) {
-					ast_channel_unlock(ast);
+				if (p->chan) {
+					ast_channel_unlock(p->chan);
 				}
 				usleep(1);
-				if (ast) {
-					ast_channel_lock(ast);
+				if (p->chan) {
+					ast_channel_lock(p->chan);
 				}
 				ast_mutex_lock(&p->lock);
 			}
@@ -563,8 +563,17 @@
 	} else {
 		ast_module_user_remove(p->u_owner);
 		while (p->chan && ast_channel_trylock(p->chan)) {
-			DEADLOCK_AVOIDANCE(&p->lock);
-		}
+				ast_mutex_unlock(&p->lock);
+				if (p->owner) {
+					ast_channel_unlock(p->owner);
+				}
+				usleep(1);
+				if (p->owner) {
+					ast_channel_lock(p->owner);
+				}
+				ast_mutex_lock(&p->lock);
+		}
+
 		p->owner = NULL;
 		if (p->chan) {
 			ast_queue_hangup(p->chan);

Modified: tags/1.4.31-rc2/include/asterisk/audiohook.h
URL: http://svnview.digium.com/svn/asterisk/tags/1.4.31-rc2/include/asterisk/audiohook.h?view=diff&rev=260062&r1=260061&r2=260062
==============================================================================
--- tags/1.4.31-rc2/include/asterisk/audiohook.h (original)
+++ tags/1.4.31-rc2/include/asterisk/audiohook.h Thu Apr 29 11:06:41 2010
@@ -69,9 +69,16 @@
  * \param chan Channel
  * \param frame Frame of audio to manipulate
  * \param direction Direction frame came from
- * \return Returns 0 on success, -1 on failure
- * \note An audiohook does not have any reference to a private data structure for manipulate types. It is up to the manipulate callback to store this data
- *       via it's own method. An example would be datastores.
+ * \return Returns 0 on success, -1 on failure.
+ * \note An audiohook does not have any reference to a private data structure for manipulate
+ *       types. It is up to the manipulate callback to store this data via it's own method.
+ *       An example would be datastores.
+ * \note The input frame should never be freed or corrupted during a manipulate callback.
+ *       If the callback has the potential to corrupt the frame's data during manipulation,
+ *       local data should be used for the manipulation and only copied to the frame on
+ *       success.
+ * \note A failure return value indicates that the frame was not manipulated and that
+ *       is being returned in its original state.
  */
 typedef int (*ast_audiohook_manipulate_callback)(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction);
 

Modified: tags/1.4.31-rc2/main/audiohook.c
URL: http://svnview.digium.com/svn/asterisk/tags/1.4.31-rc2/main/audiohook.c?view=diff&rev=260062&r1=260061&r2=260062
==============================================================================
--- tags/1.4.31-rc2/main/audiohook.c (original)
+++ tags/1.4.31-rc2/main/audiohook.c Thu Apr 29 11:06:41 2010
@@ -572,7 +572,29 @@
 	return frame;
 }
 
-/*! \brief Pass an AUDIO frame off to be handled by the audiohook core
+/*!
+ * \brief Pass an AUDIO frame off to be handled by the audiohook core
+ *
+ * \details
+ * This function has 3 ast_frames and 3 parts to handle each.  At the beginning of this
+ * function all 3 frames, start_frame, middle_frame, and end_frame point to the initial
+ * input frame.
+ *
+ * Part_1: Translate the start_frame into SLINEAR audio if it is not already in that
+ *         format.  The result of this part is middle_frame is guaranteed to be in
+ *         SLINEAR format for Part_2.
+ * Part_2: Send middle_frame off to spies and manipulators.  At this point middle_frame is
+ *         either a new frame as result of the translation, or points directly to the start_frame
+ *         because no translation to SLINEAR audio was required.  The result of this part
+ *         is end_frame will be updated to point to middle_frame if any audiohook manipulation
+ *         took place.
+ * Part_3: Translate end_frame's audio back into the format of start frame if necessary.
+ *         At this point if middle_frame != end_frame, we are guaranteed that no manipulation
+ *         took place and middle_frame can be freed as it was translated... If middle_frame was
+ *         not translated and still pointed to start_frame, it would be equal to end_frame as well
+ *         regardless if manipulation took place which would not result in this free.  The result
+ *         of this part is end_frame is guaranteed to be the format of start_frame for the return.
+ *         
  * \param chan Channel that the list is coming off of
  * \param audiohook_list List of audiohooks
  * \param direction Direction frame is coming in from
@@ -587,6 +609,7 @@
 	struct ast_audiohook *audiohook = NULL;
 	int samples = frame->samples;
 
+	/* ---Part_1. translate start_frame to SLINEAR if necessary. */
 	/* If the frame coming in is not signed linear we have to send it through the in_translate path */
 	if (frame->subclass != AST_FORMAT_SLINEAR) {
 		if (in_translate->format != frame->subclass) {
@@ -601,6 +624,7 @@
 		samples = middle_frame->samples;
 	}
 
+	/* ---Part_2: Send middle_frame to spy and manipulator lists.  middle_frame is guaranteed to be SLINEAR here.*/
 	/* Queue up signed linear frame to each spy */
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&audiohook_list->spy_list, audiohook, list) {
 		ast_audiohook_lock(audiohook);
@@ -658,19 +682,19 @@
 			}
 			/* Feed in frame to manipulation */
 			if (audiohook->manipulate_callback(audiohook, chan, middle_frame, direction)) {
-				/* Manipulation failed */
-				ast_frfree(middle_frame);
-				middle_frame = NULL;
+				/* XXX IGNORE FAILURE */
+
+				/* If the manipulation fails then the frame will be returned in its original state.
+				 * Since there are potentially more manipulator callbacks in the list, no action should
+				 * be taken here to exit early. */
 			}
 			ast_audiohook_unlock(audiohook);
 		}
 		AST_LIST_TRAVERSE_SAFE_END
-		if (middle_frame) {
-			end_frame = middle_frame;
-		}
-	}
-
-	/* Now we figure out what to do with our end frame (whether to transcode or not) */
+		end_frame = middle_frame;
+	}
+
+	/* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
 	if (middle_frame == end_frame) {
 		/* Middle frame was modified and became the end frame... let's see if we need to transcode */
 		if (end_frame->subclass != start_frame->subclass) {
@@ -695,9 +719,7 @@
 		}
 	} else {
 		/* No frame was modified, we can just drop our middle frame and pass the frame we got in out */
-		if (middle_frame) {
-			ast_frfree(middle_frame);
-		}
+		ast_frfree(middle_frame);
 	}
 
 	return end_frame;

Modified: tags/1.4.31-rc2/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/tags/1.4.31-rc2/main/channel.c?view=diff&rev=260062&r1=260061&r2=260062
==============================================================================
--- tags/1.4.31-rc2/main/channel.c (original)
+++ tags/1.4.31-rc2/main/channel.c Thu Apr 29 11:06:41 2010
@@ -1702,24 +1702,21 @@
 	int res = 0;
 
 	ast_channel_lock(chan);
-
 	if (chan->generatordata) {
 		if (chan->generator && chan->generator->release)
 			chan->generator->release(chan, chan->generatordata);
 		chan->generatordata = NULL;
 	}
-
-	ast_prod(chan);
 	if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
 		res = -1;
 	}
-	
 	if (!res) {
 		ast_settimeout(chan, 160, generator_force, chan);
 		chan->generator = gen;
 	}
-
 	ast_channel_unlock(chan);
+
+	ast_prod(chan);
 
 	return res;
 }




More information about the asterisk-commits mailing list