diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-13 15:23:19 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-10-13 15:23:19 +0000 |
commit | 5aa6e27f96b52de56bc4dda9c0d0cec8dcd11158 (patch) | |
tree | 85fb2e9c44079501a04e5ff5978aa036aaca3c21 /channels | |
parent | 2b07ca296173047645a13b835c4a9fa6b13b3508 (diff) |
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
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 17 |
1 files changed, 16 insertions, 1 deletions
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; } |