Revision
14644
Author
anthm
Date
2009-08-26 12:42:36 -0500 (Wed, 26 Aug 2009)

Log Message

add recursive flags and workaround for nested broadcast in controlled situations

Modified Paths

Diff

Modified: freeswitch/trunk/src/include/switch_channel.h (14643 => 14644)


--- freeswitch/trunk/src/include/switch_channel.h	2009-08-26 16:29:47 UTC (rev 14643)
+++ freeswitch/trunk/src/include/switch_channel.h	2009-08-26 17:42:36 UTC (rev 14644)
@@ -290,6 +290,7 @@
   \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 @@
   \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);
 

Modified: freeswitch/trunk/src/switch_channel.c (14643 => 14644)


--- freeswitch/trunk/src/switch_channel.c	2009-08-26 16:29:47 UTC (rev 14643)
+++ freeswitch/trunk/src/switch_channel.c	2009-08-26 17:42:36 UTC (rev 14644)
@@ -119,7 +119,7 @@
 	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,7 +844,21 @@
 	}
 }
 
+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)
 {
 	switch_assert(channel != NULL);
@@ -916,6 +930,22 @@
 	}
 }
 
+
+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;

Modified: freeswitch/trunk/src/switch_ivr.c (14643 => 14644)


--- freeswitch/trunk/src/switch_ivr.c	2009-08-26 16:29:47 UTC (rev 14643)
+++ freeswitch/trunk/src/switch_ivr.c	2009-08-26 17:42:36 UTC (rev 14644)
@@ -470,10 +470,10 @@
 
 	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 @@
 	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;
 }

Modified: freeswitch/trunk/src/switch_ivr_async.c (14643 => 14644)


--- freeswitch/trunk/src/switch_ivr_async.c	2009-08-26 16:29:47 UTC (rev 14643)
+++ freeswitch/trunk/src/switch_ivr_async.c	2009-08-26 17:42:36 UTC (rev 14644)
@@ -2311,6 +2311,7 @@
 	char *cause = NULL;
 	char *mypath;
 	char *p;
+	int custom = 0;
 
 	switch_assert(path);
 
@@ -2320,31 +2321,30 @@
 
 	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) {