Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 197618) +++ channels/chan_sip.c (working copy) @@ -5299,6 +5299,17 @@ char *videoqos = ""; char *textqos = ""; + /* We ned to get the lock on bridge because ast_rtp_set_vars will attempt + * to lock the bridge. This may get hairy... + */ + while (bridge && ast_channel_trylock(bridge)) { + sip_pvt_unlock(p); + do { + CHANNEL_DEADLOCK_AVOIDANCE(p->owner); + } while (sip_pvt_trylock(p)); + bridge = ast_bridged_channel(p->owner); + } + if (p->rtp) ast_rtp_set_vars(oldowner, p->rtp); @@ -5307,6 +5318,7 @@ if (IS_SIP_TECH(bridge->tech) && q && q->rtp) ast_rtp_set_vars(bridge, q->rtp); + ast_channel_unlock(bridge); } if (p->vrtp) @@ -19260,6 +19272,20 @@ struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL; char *videoqos, *textqos; + /* We ned to get the lock on bridge because ast_rtp_set_vars will attempt + * to lock the bridge. This may get hairy... + */ + while (bridge && ast_channel_trylock(bridge)) { + ast_channel_unlock(p->owner); + do { + /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */ + sip_pvt_unlock(p); + usleep(1); + sip_pvt_lock(p); + } while (ast_channel_trylock(p->owner)); + bridge = ast_bridged_channel(p->owner); + } + if (p->rtp) { if (p->do_history) { char *audioqos, @@ -19288,6 +19314,7 @@ if (IS_SIP_TECH(bridge->tech) && q && q->rtp) ast_rtp_set_vars(bridge, q->rtp); + ast_channel_unlock(bridge); } if (p->vrtp) {