Merged revisions 256014 via svnmerge from

https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r256014 | russell | 2010-04-02 18:45:56 -0500 (Fri, 02 Apr 2010) | 9 lines
  
  Resolve a deadlock that occurs due to a pointless call to ast_bridged_channel()
  
  (closes issue #16840)
  Reported by: bzing2
  Patches:
        patch.txt uploaded by bzing2 (license 902)
        issue_16840.rev1.diff uploaded by russell (license 2)
  Tested by: bzing2, russell
........


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256015 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/1.8.6
Russell Bryant 15 years ago
parent 37797ddd52
commit df3fc304c9

@ -292,7 +292,11 @@ static int local_answer(struct ast_channel *ast)
return res; return res;
} }
static void check_bridge(struct local_pvt *p, int isoutbound) /*!
* \internal
* \note This function assumes that we're only called from the "outbound" local channel side
*/
static void check_bridge(struct local_pvt *p)
{ {
struct ast_channel_monitor *tmp; struct ast_channel_monitor *tmp;
if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner || (p->chan->_bridge != ast_bridged_channel(p->chan))) if (ast_test_flag(p, LOCAL_ALREADY_MASQED) || ast_test_flag(p, LOCAL_NO_OPTIMIZATION) || !p->chan || !p->owner || (p->chan->_bridge != ast_bridged_channel(p->chan)))
@ -303,7 +307,7 @@ static void check_bridge(struct local_pvt *p, int isoutbound)
frames on the owner channel (because they would be transferred to the frames on the owner channel (because they would be transferred to the
outbound channel during the masquerade) outbound channel during the masquerade)
*/ */
if (isoutbound && p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) { if (p->chan->_bridge /* Not ast_bridged_channel! Only go one step! */ && AST_LIST_EMPTY(&p->owner->readq)) {
/* Masquerade bridged channel into owner */ /* Masquerade bridged channel into owner */
/* Lock everything we need, one by one, and give up if /* Lock everything we need, one by one, and give up if
we can't get everything. Remember, we'll get another we can't get everything. Remember, we'll get another
@ -337,26 +341,6 @@ static void check_bridge(struct local_pvt *p, int isoutbound)
ast_channel_unlock(p->chan->_bridge); ast_channel_unlock(p->chan->_bridge);
} }
} }
/* We only allow masquerading in one 'direction'... it's important to preserve the state
(group variables, etc.) that live on p->chan->_bridge (and were put there by the dialplan)
when the local channels go away.
*/
#if 0
} else if (!isoutbound && p->owner && p->owner->_bridge && p->chan && AST_LIST_EMPTY(&p->chan->readq)) {
/* Masquerade bridged channel into chan */
if (!ast_mutex_trylock(&(p->owner->_bridge)->lock)) {
if (!ast_check_hangup(p->owner->_bridge)) {
if (!ast_mutex_trylock(&p->chan->lock)) {
if (!ast_check_hangup(p->chan)) {
ast_channel_masquerade(p->chan, p->owner->_bridge);
ast_set_flag(p, LOCAL_ALREADY_MASQED);
}
ast_mutex_unlock(&p->chan->lock);
}
}
ast_mutex_unlock(&(p->owner->_bridge)->lock);
}
#endif
} }
} }
@ -377,8 +361,8 @@ static int local_write(struct ast_channel *ast, struct ast_frame *f)
/* Just queue for delivery to the other side */ /* Just queue for delivery to the other side */
ast_mutex_lock(&p->lock); ast_mutex_lock(&p->lock);
isoutbound = IS_OUTBOUND(ast, p); isoutbound = IS_OUTBOUND(ast, p);
if (f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO)) if (isoutbound && f && (f->frametype == AST_FRAME_VOICE || f->frametype == AST_FRAME_VIDEO))
check_bridge(p, isoutbound); check_bridge(p);
if (!ast_test_flag(p, LOCAL_ALREADY_MASQED)) if (!ast_test_flag(p, LOCAL_ALREADY_MASQED))
res = local_queue_frame(p, isoutbound, f, ast, 1); res = local_queue_frame(p, isoutbound, f, ast, 1);
else { else {

Loading…
Cancel
Save