diff options
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r-- | channels/chan_sip.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 77e17f6bf..378f253f9 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -28775,24 +28775,22 @@ static int sip_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl) { struct sip_pvt *p; + /* Lock the channel and the private safely. */ + ast_channel_lock(chan); p = chan->tech_pvt; if (!p) { + ast_channel_unlock(chan); 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) { + if (p->owner != chan) { + /* I suppose it could be argued that if this happens it is a bug. */ + ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); sip_pvt_unlock(p); + ast_channel_unlock(chan); return 0; } + if (udptl) { ast_udptl_get_peer(udptl, &p->udptlredirip); } else { @@ -28811,8 +28809,8 @@ 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); + ast_channel_unlock(chan); return 0; } @@ -28919,10 +28917,21 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i struct sip_pvt *p; int changed = 0; + /* Lock the channel and the private safely. */ + ast_channel_lock(chan); p = chan->tech_pvt; if (!p) { + ast_channel_unlock(chan); return -1; } + sip_pvt_lock(p); + if (p->owner != chan) { + /* I suppose it could be argued that if this happens it is a bug. */ + ast_debug(1, "The private is not owned by channel %s anymore.\n", chan->name); + sip_pvt_unlock(p); + ast_channel_unlock(chan); + return 0; + } /* Disable early RTP bridge */ if ((instance || vinstance || tinstance) && @@ -28931,25 +28940,10 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i return 0; } - /* - * 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; } @@ -28957,8 +28951,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; } @@ -29000,8 +28994,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; } |