From: Anthony Minessale Date: Tue, 28 Apr 2009 14:13:05 +0000 (+0000) Subject: FSCORE-357 X-Git-Tag: v1.0.4~1023 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93550130178fb73d67c26e73e43b5c784c4bb053;p=thirdparty%2Ffreeswitch.git FSCORE-357 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13176 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- diff --git a/src/include/switch_core.h b/src/include/switch_core.h index e1ba1ac312..f6cc1ae954 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -579,6 +579,7 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(_Inout_ switch_core_ses #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_perform_locate(const 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 diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 660040f178..ffd83211fa 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -884,6 +884,7 @@ typedef enum { 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; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 114a2e0fd9..342d0291b7 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -75,13 +75,58 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_locate(const char *u 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; diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index 603e3fd6b5..c8440f1d46 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -406,24 +406,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session) 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 @@ SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *se 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 diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 96ea48e09f..67b119e65a 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -503,32 +503,9 @@ static switch_status_t audio_bridge_on_exchange_media(switch_core_session_t *ses 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_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses 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 { diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 8de666cfb2..8d28c79bc7 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2045,6 +2045,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess 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);