From: David Vossel Date: Tue, 24 Aug 2010 16:01:51 +0000 (+0000) Subject: This fix makes sure the ast_channel hangs up correctly when the dialog's PENDING_BYE... X-Git-Tag: 1.4.37-rc1~42 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3550593f30f7fa99a99d31c0056e9e5a0e388296;p=thirdparty%2Fasterisk.git This fix makes sure the ast_channel hangs up correctly when the dialog's PENDING_BYE flag is set. When the pending bye flag is used, it is possible that the dialog will terminate and leave the sip_pvt->owner channel up. This is because we never hangup the ast_channel after sending the SIP_BYE request. When we receive the response for the SIP_BYE we set need_destroy which we would expect to destroy the dialog on the next do_monitor loop, but this is not the case. The dialog will only be destroyed once the owner is hungup even with the need_destroy flag set. This patch sets the softhangup flag on the ast_channel when a SIP_BYE request is sent as a result of the pending bye flag. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@283380 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index a7edd8a255..d52fe27ab0 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -12891,7 +12891,11 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req) } } -/*! \brief Check pending actions on SIP call */ +/*! \brief Check pending actions on SIP call + * + * \note both sip_pvt and sip_pvt's owner channel (if present) + * must be locked for this function. + */ static void check_pendings(struct sip_pvt *p) { if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) { @@ -12906,6 +12910,9 @@ static void check_pendings(struct sip_pvt *p) if (p->pendinginvite) return; + if (p->owner) { + ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV); + } /* Perhaps there is an SD change INVITE outstanding */ transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); } @@ -12933,12 +12940,22 @@ static void check_pendings(struct sip_pvt *p) static int sip_reinvite_retry(const void *data) { struct sip_pvt *p = (struct sip_pvt *) data; + struct ast_channel *owner; ast_mutex_lock(&p->lock); /* called from schedule thread which requires a lock */ + while ((owner = p->owner) && ast_channel_trylock(owner)) { + ast_mutex_unlock(&p->lock); + usleep(1); + ast_mutex_lock(&p->lock); + } ast_set_flag(&p->flags[0], SIP_NEEDREINVITE); p->waitid = -1; check_pendings(p); ast_mutex_unlock(&p->lock); + if (owner) { + ast_channel_unlock(owner); + } + return 0; }