aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlmadsen <lmadsen@f38db490-d61c-443f-a65b-d21fe96a405b>2011-02-25 20:21:38 +0000
committerlmadsen <lmadsen@f38db490-d61c-443f-a65b-d21fe96a405b>2011-02-25 20:21:38 +0000
commit207b0bcaf5bc0e9de21e9aa1285f3f3ae546aa43 (patch)
tree61c6c0cb90e26c5da9b48084913d60abd220e503
parentf90d49e07995594532d5d78432029a40f7b202cd (diff)
Update .version, ChangeLog, and merge patch from r308945
git-svn-id: http://svn.digium.com/svn/asterisk/tags/1.8.4-rc2@308988 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--.version2
-rw-r--r--ChangeLog8
-rw-r--r--channels/chan_sip.c35
3 files changed, 40 insertions, 5 deletions
diff --git a/.version b/.version
index fd69cca7c..5bd56677d 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-1.8.4-rc1
+1.8.4-rc2
diff --git a/ChangeLog b/ChangeLog
index f248c0b3c..59793098d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2011-02-25 Leif Madsen <lmadsen@digium.com>
+
+ * Asterisk 1.8.4-rc2 Released.
+
+ * Fix Deadlock with attended transfer of SIP call
+ (Closes issue #18837. Reported, patched by alecdavis. Tested by
+ alecdavid, Irontec, ZX81, cmaj)
+
2011-02-23 Leif Madsen <lmadsen@digium.com>
* Asterisk 1.8.4-rc1 Released.
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 0465cfc4e..4637678b8 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -27613,7 +27613,20 @@ static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
if (!p) {
return -1;
}
+ /*
+ * Lock both the pvt and it's owner safely.
+ */
sip_pvt_lock(p);
+ while (p->owner && ast_channel_trylock(p->owner)) {
+ sip_pvt_unlock(p);
+ usleep(1);
+ sip_pvt_lock(p);
+ }
+
+ if (!p->owner) {
+ sip_pvt_unlock(p);
+ return 0;
+ }
if (udptl) {
ast_udptl_get_peer(udptl, &p->udptlredirip);
} else {
@@ -27632,6 +27645,7 @@ static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl)
}
/* Reset lastrtprx timer */
p->lastrtprx = p->lastrtptx = time(NULL);
+ ast_channel_unlock(p->owner);
sip_pvt_unlock(p);
return 0;
}
@@ -27748,12 +27762,25 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
if (!ast_bridged_channel(chan) && !sip_cfg.directrtpsetup) /* We are in early state */
return 0;
- ast_channel_lock(chan);
+ /*
+ * Lock both the pvt and it's owner safely.
+ */
sip_pvt_lock(p);
+ while (p->owner && ast_channel_trylock(p->owner)) {
+ sip_pvt_unlock(p);
+ usleep(1);
+ sip_pvt_lock(p);
+ }
+
+ if (!p->owner) {
+ sip_pvt_unlock(p);
+ return 0;
+ }
+
if (p->alreadygone) {
/* If we're destroyed, don't bother */
+ ast_channel_unlock(p->owner);
sip_pvt_unlock(p);
- ast_channel_unlock(chan);
return 0;
}
@@ -27761,8 +27788,8 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
that are known to be behind a NAT, then stop the process now
*/
if (nat_active && !ast_test_flag(&p->flags[0], SIP_DIRECT_MEDIA_NAT)) {
+ ast_channel_unlock(p->owner);
sip_pvt_unlock(p);
- ast_channel_unlock(chan);
return 0;
}
@@ -27804,8 +27831,8 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
}
/* Reset lastrtprx timer */
p->lastrtprx = p->lastrtptx = time(NULL);
+ ast_channel_unlock(p->owner);
sip_pvt_unlock(p);
- ast_channel_unlock(chan);
return 0;
}