--- ./channels/chan_sip.c.orig 2004-09-27 10:14:10.000000000 +0200 +++ ./channels/chan_sip.c 2004-10-02 03:27:10.000000000 +0200 @@ -1546,6 +1546,9 @@ struct sip_pkt *cp; struct sip_history *hist; + /* Use the peer lock to prevent destruction of a call which is waiting + * inside a lenghty find_peer */ + ast_mutex_lock(&peerl.lock); if (sip_debug_test_pvt(p)) ast_verbose("Destroying call '%s'\n", p->callid); if (p->stateid > -1) @@ -1618,6 +1621,7 @@ ast_mutex_destroy(&p->lock); free(p); } + ast_mutex_unlock(&peerl.lock); } /*--- update_user_counter: Handle incominglimit and outgoinglimit for SIP users ---*/ @@ -4833,7 +4837,24 @@ strncpy(p->exten, name, sizeof(p->exten) - 1); build_contact(p); ast_mutex_lock(&peerl.lock); + /* find peer may take a while so we release the two other locks*/ + if (p->owner) + ast_mutex_unlock(&p->owner->lock); + ast_mutex_unlock(&p->lock); peer = find_peer(name, NULL); + /* now try to reaquire the locks */ + for (;;) + { + ast_mutex_lock(&p->lock); + if (p->owner && ast_mutex_trylock(&p->owner->lock)) { + ast_log(LOG_DEBUG, "Failed to grab back lock, trying again...\n"); + ast_mutex_unlock(&p->lock); + usleep(1); + } else + break; + } + + if (!(peer && ast_apply_ha(peer->ha, sin))) { if (peer && peer->temponly) { if (peer->ha) {