[Freeswitch-svn] [commit] r13176 - in freeswitch/trunk/src: . include

FreeSWITCH SVN anthm at freeswitch.org
Tue Apr 28 07:13:05 PDT 2009


Author: anthm
Date: Tue Apr 28 09:13:05 2009
New Revision: 13176

Log:
FSCORE-357

Modified:
   freeswitch/trunk/src/include/switch_core.h
   freeswitch/trunk/src/include/switch_types.h
   freeswitch/trunk/src/switch_core_session.c
   freeswitch/trunk/src/switch_core_state_machine.c
   freeswitch/trunk/src/switch_ivr_bridge.c
   freeswitch/trunk/src/switch_ivr_originate.c

Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h	(original)
+++ freeswitch/trunk/src/include/switch_core.h	Tue Apr 28 09:13:05 2009
@@ -579,6 +579,7 @@
 #define switch_core_session_destroy(session) switch_core_session_perform_destroy(session, __FILE__, __SWITCH_FUNC__, __LINE__)
 
 SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session);
 
 /*! 
   \brief Provide the total number of sessions
@@ -652,6 +653,13 @@
 SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(_In_z_ const char *uuid_str);
 #endif
 
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+#define switch_core_session_locate(uuid_str) switch_core_session_perform_force_locate(uuid_str, __FILE__, __SWITCH_FUNC__, __LINE__)
+#else
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_force_locate(_In_z_ const char *uuid_str);
+#endif
+
 /*! 
   \brief Retrieve a global variable from the core
   \param varname the name of the variable

Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h	(original)
+++ freeswitch/trunk/src/include/switch_types.h	Tue Apr 28 09:13:05 2009
@@ -884,6 +884,7 @@
 	CF_DIVERT_EVENTS,
 	CF_BLOCK_STATE,
 	CF_FS_RTP,
+	CF_REPORTING,
 	/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
 	CF_FLAG_MAX
 } switch_channel_flag_t;

Modified: freeswitch/trunk/src/switch_core_session.c
==============================================================================
--- freeswitch/trunk/src/switch_core_session.c	(original)
+++ freeswitch/trunk/src/switch_core_session.c	Tue Apr 28 09:13:05 2009
@@ -75,13 +75,58 @@
 	return session;
 }
 
+
+
+
+#ifdef SWITCH_DEBUG_RWLOCKS
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_perform_force_locate(const char *uuid_str, const char *file, const char *func, int line)
+#else
+SWITCH_DECLARE(switch_core_session_t *) switch_core_session_force_locate(const char *uuid_str)
+#endif
+{
+	switch_core_session_t *session = NULL;
+	switch_status_t status;
+	
+	if (uuid_str) {
+		switch_mutex_lock(runtime.session_hash_mutex);
+		if ((session = switch_core_hash_find(session_manager.session_table, uuid_str))) {
+			/* Acquire a read lock on the session */
+
+			if (switch_test_flag(session, SSF_DESTROYED)) {
+				status = SWITCH_STATUS_FALSE;
+#ifdef SWITCH_DEBUG_RWLOCKS
+				switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "%s Read lock FAIL\n",
+								  switch_channel_get_name(session->channel));
+#endif
+			} else {
+				status = (switch_status_t) switch_thread_rwlock_tryrdlock(session->rwlock);
+#ifdef SWITCH_DEBUG_RWLOCKS
+				switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "%s Read lock ACQUIRED\n",
+								  switch_channel_get_name(session->channel));
+#endif
+			}
+
+			if (status != SWITCH_STATUS_SUCCESS) {
+				/* not available, forget it */
+				session = NULL;
+			}
+		}
+		switch_mutex_unlock(runtime.session_hash_mutex);
+	}
+
+	/* if its not NULL, now it's up to you to rwunlock this */
+	return session;
+}
+
+
 SWITCH_DECLARE(switch_status_t) switch_core_session_get_partner(switch_core_session_t *session, switch_core_session_t **partner)
 {
 	const char *uuid;
 	
 	if ((uuid = switch_channel_get_variable(session->channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
-		*partner = switch_core_session_locate(uuid);
-		return SWITCH_STATUS_SUCCESS;
+		if ((*partner = switch_core_session_locate(uuid))) {
+			return SWITCH_STATUS_SUCCESS;
+		}
 	}
 
 	*partner = NULL;

Modified: freeswitch/trunk/src/switch_core_state_machine.c
==============================================================================
--- freeswitch/trunk/src/switch_core_state_machine.c	(original)
+++ freeswitch/trunk/src/switch_core_state_machine.c	Tue Apr 28 09:13:05 2009
@@ -406,24 +406,7 @@
 				goto done;
 			case CS_REPORTING: /* Call Detail */
 				{
-					const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
-					
-					if (!switch_strlen_zero(var)) {
-						if (!strcasecmp(var, "a_only")) {
-							if (switch_channel_get_originator_caller_profile(session->channel)) {
-								do_extra_handlers = 0;
-							}
-						} else if (!strcasecmp(var, "b_only")) {
-							if (switch_channel_get_originatee_caller_profile(session->channel)) {
-								do_extra_handlers = 0;
-							}
-						} else if (!switch_true(var)) {
-							do_extra_handlers = 0;
-						}
-					}
-
-					STATE_MACRO(reporting, "REPORTING");
-					
+					switch_core_session_reporting_state(session);
 					switch_channel_set_state(session->channel, CS_DESTROY);
 				}
 				goto done;
@@ -578,6 +561,56 @@
 	return;
 }
 
+
+SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *session)
+{
+	switch_channel_state_t state = switch_channel_get_state(session->channel), midstate = state;
+	const switch_endpoint_interface_t *endpoint_interface;
+	const switch_state_handler_table_t *driver_state_handler = NULL;
+	const switch_state_handler_table_t *application_state_handler = NULL;
+	int proceed = 1;
+	int global_proceed = 1;
+	int do_extra_handlers = 1;
+	int silly = 0;
+	int index = 0;
+
+	if (switch_channel_test_flag(session->channel, CF_REPORTING)) {
+		return;
+	}
+
+	switch_channel_set_flag(session->channel, CF_REPORTING);
+	
+	switch_assert(session != NULL);
+
+	session->thread_running = 1;
+	endpoint_interface = session->endpoint_interface;
+	switch_assert(endpoint_interface != NULL);
+
+	driver_state_handler = endpoint_interface->state_handler;
+	switch_assert(driver_state_handler != NULL);
+	
+
+	const char *var = switch_channel_get_variable(session->channel, SWITCH_PROCESS_CDR_VARIABLE);
+	
+	if (!switch_strlen_zero(var)) {
+		if (!strcasecmp(var, "a_only")) {
+			if (switch_channel_get_originator_caller_profile(session->channel)) {
+				do_extra_handlers = 0;
+			}
+		} else if (!strcasecmp(var, "b_only")) {
+			if (switch_channel_get_originatee_caller_profile(session->channel)) {
+				do_extra_handlers = 0;
+			}
+		} else if (!switch_true(var)) {
+			do_extra_handlers = 0;
+		}
+	}
+
+	STATE_MACRO(reporting, "REPORTING");
+					
+	return;
+}
+
 /* For Emacs:
  * Local Variables:
  * mode:c

Modified: freeswitch/trunk/src/switch_ivr_bridge.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_bridge.c	(original)
+++ freeswitch/trunk/src/switch_ivr_bridge.c	Tue Apr 28 09:13:05 2009
@@ -503,32 +503,9 @@
 		if (!switch_channel_test_flag(channel, CF_TRANSFER) && !switch_channel_test_flag(channel, CF_REDIRECT) && bd && !bd->clean_exit 
 			&& state != CS_PARK && state != CS_ROUTING && !switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
 			switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
-			}
-	}
-	
-
-	if (switch_true(switch_channel_get_variable(channel, SWITCH_COPY_XML_CDR_VARIABLE))) {
-		switch_core_session_t *other_session;
-		switch_channel_t *other_channel;
-		switch_xml_t cdr;
-		char *xml_text;
-
-		if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) {
-			other_channel = switch_core_session_get_channel(other_session);
-			
-			switch_channel_wait_for_state(channel, other_channel, CS_REPORTING);
-			
-			if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
-				if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
-					switch_channel_set_variable(other_channel, "b_leg_cdr", xml_text);
-					switch_safe_free(xml_text);
-				}
-				switch_xml_free(cdr);
-			}
-			switch_core_session_rwunlock(other_session);
 		}
 	}
-
+	
 	if (switch_channel_get_state(channel) == CS_EXCHANGE_MEDIA) {
 		switch_channel_set_state(channel, CS_RESET);
 	}
@@ -979,6 +956,21 @@
 				switch_channel_set_variable(caller_channel, SWITCH_BRIDGE_HANGUP_CAUSE_VARIABLE, switch_channel_cause2str(cause));
 			}
 
+			if (switch_channel_down(peer_channel) && switch_true(switch_channel_get_variable(peer_channel, SWITCH_COPY_XML_CDR_VARIABLE))) {
+				switch_xml_t cdr;
+				char *xml_text;
+				
+				switch_channel_wait_for_state(caller_channel, peer_channel, CS_DESTROY);
+
+				if (switch_ivr_generate_xml_cdr(peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
+					if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
+						switch_channel_set_variable(caller_channel, "b_leg_cdr", xml_text);
+						switch_safe_free(xml_text);
+					}
+					switch_xml_free(cdr);
+				}
+			}
+
 			switch_core_session_rwunlock(peer_session);
 
 		} else {

Modified: freeswitch/trunk/src/switch_ivr_originate.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_originate.c	(original)
+++ freeswitch/trunk/src/switch_ivr_originate.c	Tue Apr 28 09:13:05 2009
@@ -2045,6 +2045,8 @@
                             continue;
                         }
 						
+						switch_channel_wait_for_state(caller_channel, switch_core_session_get_channel(originate_status[i].peer_session), CS_DESTROY);
+
 						if (switch_ivr_generate_xml_cdr(originate_status[i].peer_session, &cdr) == SWITCH_STATUS_SUCCESS) {
 							if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) {
 								switch_snprintf(buf, sizeof(buf), "%s_%d", cdr_var, ++cdr_total);



More information about the Freeswitch-svn mailing list