[asterisk-commits] Frame deferral: Re-queue deferred frames one-at-a-time. (asterisk[certified/13.13])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Dec 1 13:10:01 CST 2016


Anonymous Coward #1000019 has submitted this change and it was merged. ( https://gerrit.asterisk.org/4533 )

Change subject: Frame deferral: Re-queue deferred frames one-at-a-time.
......................................................................


Frame deferral: Re-queue deferred frames one-at-a-time.

The recent change that made frame deferral into an API had a behavior
change to it. When frame deferral was completed, we would take all of
the deferred frames and queue them all onto the channel in one call to
ast_queue_frame_head(). Before frame deferral was API-ized, places that
performed manual frame deferral would actually take each deferred frame
and queue them onto the channel.

This change in behavior caused the confbridge_recording test to start
failing consistently. Without going too crazily deep into the details,
a channel was getting "stuck" in an ast_safe_sleep(). An AMI redirect
was attempting to break it out of the sleep, but because there were more
frames in the channel read queue than expected, the channel ended up
being unable to break from its sleep loop.

By restoring the behavior of individual frame queuing after deferral,
the test starts passing again.

Note, this points to a potential underlying issue pointing to an
"unbalance" that can occur when queuing multiple frames at once,
and so a follow-up issue is being created to investigate that
possibility.

Change-Id: Ied5dacacda06d343dea751ed5814a03364fe5a7d
---
M main/channel.c
1 file changed, 7 insertions(+), 8 deletions(-)

Approvals:
  George Joseph: Looks good to me, approved
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, but someone else must approve



diff --git a/main/channel.c b/main/channel.c
index 54b9130..972853b 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1069,16 +1069,15 @@
 
 void ast_channel_stop_defer_frames(struct ast_channel *chan)
 {
+	struct ast_frame *f;
+
 	ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DEFER_FRAMES);
 
 	/* Move the deferred frames onto the channel read queue, ahead of other queued frames */
-	ast_queue_frame_head(chan, AST_LIST_FIRST(ast_channel_deferred_readq(chan)));
-	/* ast_frfree will mosey down the list and free them all */
-	if (!AST_LIST_EMPTY(ast_channel_deferred_readq(chan))) {
-		ast_frfree(AST_LIST_FIRST(ast_channel_deferred_readq(chan)));
+	while ((f = AST_LIST_REMOVE_HEAD(ast_channel_deferred_readq(chan), frame_list))) {
+		ast_queue_frame_head(chan, f);
+		ast_frfree(f);
 	}
-	/* Reset the list to be empty */
-	AST_LIST_HEAD_INIT_NOLOCK(ast_channel_deferred_readq(chan));
 }
 
 static int __ast_queue_frame(struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after)
@@ -3903,10 +3902,10 @@
 							struct ast_frame *dup;
 
 							dup = ast_frdup(f);
-							AST_LIST_INSERT_TAIL(ast_channel_deferred_readq(chan), dup, frame_list);
+							AST_LIST_INSERT_HEAD(ast_channel_deferred_readq(chan), dup, frame_list);
 						}
 					} else {
-						AST_LIST_INSERT_TAIL(ast_channel_deferred_readq(chan), f, frame_list);
+						AST_LIST_INSERT_HEAD(ast_channel_deferred_readq(chan), f, frame_list);
 						AST_LIST_REMOVE_CURRENT(frame_list);
 					}
 				}

-- 
To view, visit https://gerrit.asterisk.org/4533
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ied5dacacda06d343dea751ed5814a03364fe5a7d
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: certified/13.13
Gerrit-Owner: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>



More information about the asterisk-commits mailing list