summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2007-11-05 20:14:48 +0000
committerRussell Bryant <russell@russellbryant.com>2007-11-05 20:14:48 +0000
commit7df9905e712cf1c2a123498c5b65b68239686636 (patch)
treec731d941e6e38a5083a05428c94eeba93d97c864 /main
parenta6ee4667da22ba08a0aeda18d176bf56e8900fc3 (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: https://origsvn.digium.com/svn/asterisk/trunk@88710 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-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