From db88d24b256d386989759b841aaadb8a72267de1 Mon Sep 17 00:00:00 2001 From: ddegroot Date: Mon, 25 Jan 2016 20:46:40 +0000 Subject: [PATCH] Fix: make shure scheduled events return 0 when exiting, so that the event is cancelled. Take and Release and extra ref during when returning from a scheduled event to re-check if the object still exists. Release both the scheduled obj reference and the locally takes reference, before exiting the scheduled function. git-svn-id: https://svn.code.sf.net/p/chan-sccp-b/code/trunk@6532 43c1dc8c-776e-4df2-8ef1-6e829299be21 --- src/sccp_channel.c | 8 ++------ src/sccp_pbx.c | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/sccp_channel.c b/src/sccp_channel.c index 739d9deea0..89fbe034fd 100644 --- a/src/sccp_channel.c +++ b/src/sccp_channel.c @@ -1134,10 +1134,6 @@ void sccp_channel_end_forwarding_channel(sccp_channel_t * orig_channel) static int _sccp_channel_sched_endcall(const void *data) { AUTO_RELEASE sccp_channel_t *channel = NULL; - if (!data) { - return -1; - } - if ((channel = sccp_channel_retain(data))) { channel->scheduler.hangup_id = -3; sccp_log(DEBUGCAT_CHANNEL) ("%s: Scheduled Hangup\n", channel->designator); @@ -1145,9 +1141,9 @@ static int _sccp_channel_sched_endcall(const void *data) sccp_channel_stop_and_deny_scheduled_tasks(channel); sccp_channel_endcall(channel); } - sccp_channel_release(data); /* explicit release of the ref taken when creating the scheduled hangup */ + sccp_channel_release(data); // release channel retained in scheduled event } - return 0; + return 0; // return 0 to release schedule } /* diff --git a/src/sccp_pbx.c b/src/sccp_pbx.c index a04633aaf6..7951e20048 100644 --- a/src/sccp_pbx.c +++ b/src/sccp_pbx.c @@ -992,23 +992,22 @@ uint8_t sccp_pbx_channel_allocate(sccp_channel_t * channel, const void *ids, con */ int sccp_pbx_sched_dial(const void * data) { - sccp_channel_t * c = (sccp_channel_t *) data; // channel already retained in data, unlocked at end of sched_replace_ref - if (c) { - c->scheduler.digittimeout_id = -3; - if (c->scheduler.hangup_id == -1) { - if (c->owner && !iPbx.getChannelPbx(c) && !sccp_strlen_zero(c->dialedNumber)) { - sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_1 "SCCP: Timeout for call '%s'. Going to dial '%s'\n", c->designator, c->dialedNumber); - sccp_pbx_softswitch(c); - return 0; + AUTO_RELEASE sccp_channel_t *channel = NULL; + if ((channel = sccp_channel_retain(data))) { + if ((ATOMIC_FETCH(&channel->scheduler.deny, &channel->scheduler.lock) == 0) && channel->scheduler.hangup_id == -1) { + channel->scheduler.digittimeout_id = -3; /* prevent further digittimeout scheduling */ + if (channel->owner && !iPbx.getChannelPbx(channel) && !sccp_strlen_zero(channel->dialedNumber)) { + sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_1 "SCCP: Timeout for call '%s'. Going to dial '%s'\n", channel->designator, channel->dialedNumber); + sccp_pbx_softswitch(channel); + } else { + sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_1 "SCCP: Timeout for call '%s'. Nothing to dial -> INVALIDNUMBER\n", channel->designator); + channel->dialedNumber[0] = '\0'; + sccp_indicate(NULL, channel, SCCP_CHANNELSTATE_INVALIDNUMBER); } - // fall through - sccp_log((DEBUGCAT_CORE)) (VERBOSE_PREFIX_1 "SCCP: Timeout for call '%s'. Nothing to dial -> INVALIDNUMBER\n", c->designator); - c->dialedNumber[0] = '\0'; - sccp_indicate(NULL, c, SCCP_CHANNELSTATE_INVALIDNUMBER); - sccp_channel_release(c); } + sccp_channel_release(data); // release channel retained in scheduled event } - return -1; + return 0; // return 0 to release schedule } /*!