]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add recursive flags and workaround for nested broadcast in controlled situations
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 26 Aug 2009 17:42:36 +0000 (17:42 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 26 Aug 2009 17:42:36 +0000 (17:42 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14644 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_channel.h
src/switch_channel.c
src/switch_ivr.c
src/switch_ivr_async.c

index 1764c7b17e582d0d2493d02faf2b6ceba3392419..c4d4e6d12b9e87c5fd26ad72561675f0e2a63352 100644 (file)
@@ -290,6 +290,7 @@ SWITCH_DECLARE(uint32_t) switch_channel_test_flag(switch_channel_t *channel, swi
   \param flag or'd list of flags to set
 */
 SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flag);
+SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag);
 
 /*!
   \brief Set given flag(s) on a given channel's bridge partner
@@ -322,6 +323,7 @@ SWITCH_DECLARE(void) switch_channel_set_state_flag(switch_channel_t *channel, sw
   \param flag flag to clear
 */
 SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag);
+SWITCH_DECLARE(void) switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag);
 
 SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel, const char *file, const char *func, int line);
 
index 710da181df4e43780c2c0ccd102a8b239980a814..141a1d2f5718e8423ca676fb4d4a42dc84eeb37a 100644 (file)
@@ -119,7 +119,7 @@ struct switch_channel {
        switch_core_session_t *session;
        switch_channel_state_t state;
        switch_channel_state_t running_state;
-       uint8_t flags[CF_FLAG_MAX];
+       uint32_t flags[CF_FLAG_MAX];
        uint8_t state_flags[CF_FLAG_MAX];
        uint32_t private_flags;
        uint32_t app_flags;
@@ -844,6 +844,20 @@ SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_c
        }
 }
 
+SWITCH_DECLARE(void) switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
+{
+       switch_assert(channel);
+       switch_assert(channel->flag_mutex);
+
+       switch_mutex_lock(channel->flag_mutex);
+       channel->flags[flag]++;
+       switch_mutex_unlock(channel->flag_mutex);
+
+       if (flag == CF_OUTBOUND) {
+               switch_channel_set_variable(channel, "is_outbound", "true");
+       }
+}
+
 
 SWITCH_DECLARE(void) switch_channel_set_private_flag(switch_channel_t *channel, uint32_t flags)
 {
@@ -916,6 +930,22 @@ SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch
        }
 }
 
+
+SWITCH_DECLARE(void) switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
+{
+       switch_assert(channel != NULL);
+       switch_assert(channel->flag_mutex);
+
+       switch_mutex_lock(channel->flag_mutex);
+       if (channel->flags[flag]) {
+               channel->flags[flag]--;
+       }
+       switch_mutex_unlock(channel->flag_mutex);
+       if (flag == CF_OUTBOUND) {
+               switch_channel_set_variable(channel, "is_outbound", NULL);
+       }
+}
+
 SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t *channel)
 {
        switch_channel_state_t state;
index 176ddf034db340cc7dedb6d2c73b3f28cd806fd0..fa33ea1decea5722a13b6163b1a070ba22b92466 100644 (file)
@@ -470,10 +470,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
 
        cmd_hash = switch_hashfunc_default(cmd, &hlen);
 
-       switch_channel_set_flag(channel, CF_EVENT_PARSE);
+       switch_channel_set_flag_recursive(channel, CF_EVENT_PARSE);
 
        if (switch_true(event_lock)) {
-               switch_channel_set_flag(channel, CF_EVENT_LOCK);
+               switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK);
        }
 
        if (lead_frames) {
@@ -604,8 +604,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
        status = SWITCH_STATUS_SUCCESS;
 
   done:
-       switch_channel_clear_flag(channel, CF_EVENT_PARSE);
-       switch_channel_clear_flag(channel, CF_EVENT_LOCK);
+       switch_channel_clear_flag_recursive(channel, CF_EVENT_PARSE);
+       switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK);
 
        return status;
 }
index c5fd4d9fae8132b2cc22b981a96b173c08032ad5..3f5fa5a94e7818706aa37545ca1596bb8a3bb06e 100644 (file)
@@ -2311,6 +2311,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
        char *cause = NULL;
        char *mypath;
        char *p;
+       int custom = 0;
 
        switch_assert(path);
 
@@ -2320,31 +2321,30 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
 
        channel = switch_core_session_get_channel(session);
 
-       if ((switch_channel_test_flag(channel, CF_EVENT_PARSE))) {
+       mypath = strdup(path);
+       assert(mypath);
+
+       if ((p = strchr(mypath, ':')) && *(p + 1) == ':') {
+               app = mypath;
+               *p++ = '\0';
+               *p++ = '\0';
+               path = p;
+               custom++;
+       }
+
+       if (!custom && (switch_channel_test_flag(channel, CF_EVENT_PARSE))) {
                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel [%s][%s] already broadcasting...broadcast aborted\n",
                                                  switch_channel_get_name(channel), path);
                switch_core_session_rwunlock(session);
+               switch_safe_free(mypath);               
                return SWITCH_STATUS_FALSE;
        }
 
-       mypath = strdup(path);
-
-       if (!mypath) {
-               switch_core_session_rwunlock(session);
-               return SWITCH_STATUS_MEMERR;
-       }
 
        if ((nomedia = switch_channel_test_flag(channel, CF_PROXY_MODE))) {
                switch_ivr_media(uuid, SMF_REBRIDGE);
        }
 
-       if ((p = strchr(mypath, ':')) && *(p + 1) == ':') {
-               app = mypath;
-               *p++ = '\0';
-               *p++ = '\0';
-               path = p;
-       }
-
        if ((cause = strchr(app, '!'))) {
                *cause++ = '\0';
                if (!cause) {