}
}
-/*! \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)) {
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);
}
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;
}