diff --git a/channels/chan_sip.c b/channels/chan_sip.c index de23063..74ea9cd 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -25828,11 +25828,32 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str goto request_invite_cleanup; } + /* We cannot call sip_new with any locks held. + * Unlock the referred channel if locked. */ + if (refer_locked) { + sip_pvt_unlock(p->refer->refer_call); + if (p->refer->refer_call->owner) { + ast_channel_unlock(p->refer->refer_call->owner); + } + } + /* First invitation - create the channel. Allocation * failures are handled below. */ - c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL, p->logger_callid); + /* Reacquire the lock on the referred call. */ + if (refer_locked) { + /* Reuse pattern found in get_sip_pvt_byid_locked. */ + sip_pvt_lock(p->refer->refer_call); + while (p->refer->refer_call->owner && ast_channel_trylock(p->refer->refer_call->owner)) { + sip_pvt_unlock(p->refer->refer_call); + usleep(1); + sip_pvt_lock(p->refer->refer_call); + } + } + + /* XXX: todo: check that the channel is unmodified and available? */ + if (cc_recall_core_id != -1) { ast_setup_cc_recall_datastore(c, cc_recall_core_id); ast_cc_agent_set_interfaces_chanvar(c);