aboutsummaryrefslogtreecommitdiffstats
path: root/main/channel.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-11-05 20:14:48 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-11-05 20:14:48 +0000
commitf2977f1903a41cd2c5299adb648242cc28421891 (patch)
treec731d941e6e38a5083a05428c94eeba93d97c864 /main/channel.c
parente9521cd0c93aba107016985853c51e05f1eb320f (diff)
Merged revisions 88709 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r88709 | russell | 2007-11-05 14:11:04 -0600 (Mon, 05 Nov 2007) | 20 lines Merge the last bit of changes from asterisk/team/russell/readq-1.4 The issue here is that the channel frame readq handling got broken when the code was converted to use the linked list macros. It caused corruption of the list head and tail pointers. So, I fixed up the usage of the linked list macros and in passing, simplified the code. I also documented what the code is doing, as it was a bit difficult to figure out at first. This bug showed itself with crashes showing messed up head/tail pointers for the readq. However, there are a couple of crashes that aren't quite as obvious, but I think may be related. So, if your bug gets closed by this commit, but you still have a problem, please reopen or create a new bug report. (closes issue #10936) (closes issue #10595) (closes issue #10368) (closes issue #11084) (closes issue #10040) (closes issue #10840) ........ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@88710 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/channel.c')
-rw-r--r--main/channel.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/main/channel.c b/main/channel.c
index d5fcb0a2d..d23c2b93d 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -3602,11 +3602,6 @@ int ast_do_masquerade(struct ast_channel *original)
original->tech_pvt = clone->tech_pvt;
clone->tech_pvt = t_pvt;
- /* Swap the readq's */
- cur = AST_LIST_FIRST(&original->readq);
- AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq));
- AST_LIST_HEAD_SET_NOLOCK(&clone->readq, cur);
-
/* Swap the alertpipes */
for (i = 0; i < 2; i++) {
x = original->alertpipe[i];
@@ -3614,6 +3609,33 @@ int ast_do_masquerade(struct ast_channel *original)
clone->alertpipe[i] = x;
}
+ /*
+ * Swap the readq's. The end result should be this:
+ *
+ * 1) All frames should be on the new (original) channel.
+ * 2) Any frames that were already on the new channel before this
+ * masquerade need to be at the end of the readq, after all of the
+ * frames on the old (clone) channel.
+ * 3) The alertpipe needs to get poked for every frame that was already
+ * on the new channel, since we are now using the alert pipe from the
+ * old (clone) channel.
+ */
+ {
+ AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
+ AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
+
+ AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
+ AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
+
+ while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
+ AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
+ if (original->alertpipe[1] > -1) {
+ int poke = 0;
+ write(original->alertpipe[1], &poke, sizeof(poke));
+ }
+ }
+ }
+
/* Swap the raw formats */
x = original->rawreadformat;
original->rawreadformat = clone->rawreadformat;
@@ -3622,27 +3644,8 @@ int ast_do_masquerade(struct ast_channel *original)
original->rawwriteformat = clone->rawwriteformat;
clone->rawwriteformat = x;
- /* Save any pending frames on both sides. Start by counting
- * how many we're going to need... */
- x = 0;
- if (original->alertpipe[1] > -1) {
- AST_LIST_TRAVERSE(&clone->readq, cur, frame_list)
- x++;
- }
-
- /* If we had any, prepend them to the ones already in the queue, and
- * load up the alertpipe */
- if (AST_LIST_FIRST(&clone->readq)) {
- AST_LIST_INSERT_TAIL(&clone->readq, AST_LIST_FIRST(&original->readq), frame_list);
- AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq));
- AST_LIST_HEAD_SET_NOLOCK(&clone->readq, NULL);
- for (i = 0; i < x; i++)
- write(original->alertpipe[1], &x, sizeof(x));
- }
-
clone->_softhangup = AST_SOFTHANGUP_DEV;
-
/* And of course, so does our current state. Note we need not
call ast_setstate since the event manager doesn't really consider
these separate. We do this early so that the clone has the proper