From 5aa6e27f96b52de56bc4dda9c0d0cec8dcd11158 Mon Sep 17 00:00:00 2001 From: russell Date: Wed, 13 Oct 2010 15:23:19 +0000 Subject: Lock pvt so pvt->owner can't disappear when queueing up a frame. This fixes a crash due to a hangup race condition. ABE-2601 git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@291392 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_sip.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'channels') diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 413a03c58..1d693a18e 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -2214,16 +2214,31 @@ static int __sip_autodestruct(const void *data) if (option_debug) ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", p->callid); append_history(p, "AutoDestroy", "%s", p->callid); + + /* + * Lock both the pvt and the channel safely so that we can queue up a frame. + */ + ast_mutex_lock(&p->lock); + while (p->owner && ast_channel_trylock(p->owner)) { + DEADLOCK_AVOIDANCE(&p->lock); + } + if (p->owner) { ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text); ast_queue_hangup(p->owner); + ast_channel_unlock(p->owner); + ast_mutex_unlock(&p->lock); } else if (p->refer && !ast_test_flag(&p->flags[0], SIP_ALREADYGONE)) { if (option_debug > 2) ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", p->callid); transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); - } else + ast_mutex_unlock(&p->lock); + } else { + ast_mutex_unlock(&p->lock); sip_destroy(p); + } + return 0; } -- cgit v1.2.3