--- asterisk/channels/chan_mgcp.c.orig 2010-05-30 23:12:24.000000000 +0000 +++ asterisk/channels/chan_mgcp.c 2010-05-30 23:44:44.000000000 +0000 @@ -3163,20 +3163,21 @@ if (ast_bridged_channel(p->sub->next->owner)) ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD); if (p->sub->owner->_state == AST_STATE_RINGING) { - ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); + ast_indicate(ast_bridged_channel(p->sub->owner), AST_CONTROL_RINGING); } if (ast_channel_masquerade(p->sub->next->owner, ast_bridged_channel(p->sub->owner))) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", ast_bridged_channel(p->sub->owner)->name, p->sub->next->owner->name); return -1; } - /* Orphan the channel */ + /* Orphan the channel after releasing the lock */ + ast_mutex_unlock(&p->sub->next->lock); unalloc_sub(p->sub->next); } else if (ast_bridged_channel(p->sub->next->owner)) { - if (p->sub->owner->_state == AST_STATE_RINGING) { + ast_queue_control(p->sub->owner, AST_CONTROL_UNHOLD); + if (p->sub->next->owner->_state == AST_STATE_RINGING) { ast_indicate(ast_bridged_channel(p->sub->next->owner), AST_CONTROL_RINGING); } - ast_queue_control(p->sub->next->owner, AST_CONTROL_UNHOLD); if (ast_channel_masquerade(p->sub->owner, ast_bridged_channel(p->sub->next->owner))) { ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n", ast_bridged_channel(p->sub->next->owner)->name, p->sub->owner->name); @@ -3185,6 +3186,7 @@ /*swap_subs(p, SUB_THREEWAY, SUB_REAL);*/ ast_verb(3, "Swapping %d for %d on %s@%s\n", p->sub->id, p->sub->next->id, p->name, p->parent->name); p->sub = p->sub->next; + ast_mutex_unlock(&p->sub->lock); unalloc_sub(p->sub->next); /* Tell the caller not to hangup */ return 1; @@ -3459,7 +3461,8 @@ } } else if (res) { ast_log(LOG_WARNING, "Transfer attempt failed\n"); - ast_mutex_unlock(&p->sub->next->lock); + if (p->sub->next->owner) + ast_mutex_unlock(&p->sub->next->lock); return -1; } ast_mutex_unlock(&p->sub->next->lock);