]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
stop race condition in sofia where we tried to send an ack on a dead call and turn...
authorAnthony Minessale <anthony.minessale@gmail.com>
Fri, 11 Dec 2009 00:28:54 +0000 (00:28 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Fri, 11 Dec 2009 00:28:54 +0000 (00:28 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15891 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_core.h
src/include/switch_types.h
src/mod/applications/mod_dptools/mod_dptools.c
src/mod/endpoints/mod_sofia/sofia.c
src/switch_channel.c
src/switch_core.c
src/switch_core_state_machine.c
src/switch_cpp.cpp

index d96a9dbabb620642f67bdd8221b36274a3fa5286..6ce6db4c41eebec30ec6fc5d62f1da914d5e6812 100644 (file)
@@ -615,7 +615,7 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(_Inout_ switch_core_ses
 
 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);
-SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session);
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force);
 
 /*! 
   \brief Provide the total number of sessions
index c94b1eddb7d1c1cb1a5f21078acbb0038217fe21..64974c1fdd291d32de860d992eb4259f57df96a3 100644 (file)
@@ -241,7 +241,8 @@ typedef enum {
        SCF_VG = (1 << 3),
        SCF_RESTART = (1 << 4),
        SCF_SHUTDOWN_REQUESTED = (1 << 5),
-       SCF_USE_AUTO_NAT = (1 << 6)
+       SCF_USE_AUTO_NAT = (1 << 6),
+       SCF_EARLY_HANGUP = (1 << 7)
 } switch_core_flag_enum_t;
 typedef uint32_t switch_core_flag_t;
 
@@ -946,6 +947,7 @@ typedef enum {
        CF_BYPASS_MEDIA_AFTER_BRIDGE,
        CF_LEG_HOLDING,
        CF_BROADCAST_DROP_MEDIA,
+       CF_EARLY_HANGUP,
        /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
        CF_FLAG_MAX
 } switch_channel_flag_t;
index c8b71e3e146fec8f4ce63b6a30957d139f3446f6..a668f143763f58fe767f0b6ec30a84b019cb3f82 100644 (file)
@@ -2787,6 +2787,11 @@ SWITCH_STANDARD_APP(verbose_events_function)
        switch_channel_set_flag(switch_core_session_get_channel(session), CF_VERBOSE_EVENTS);
 }
 
+SWITCH_STANDARD_APP(early_hangup_function)
+{
+       switch_channel_set_flag(switch_core_session_get_channel(session), CF_EARLY_HANGUP);
+}
+
 #define WAIT_FOR_SILENCE_SYNTAX "<silence_thresh> <silence_hits> <listen_hits> <timeout_ms> [<file>]"
 SWITCH_STANDARD_APP(wait_for_silence_function)
 {
@@ -2939,6 +2944,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
        SWITCH_ADD_APP(app_interface, "check_acl", "Check an ip against an ACL list", "Check an ip against an ACL list", check_acl_function,
                                   "<ip> <acl | cidr> [<hangup_cause>]", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
        SWITCH_ADD_APP(app_interface, "verbose_events", "Make ALL Events verbose.", "Make ALL Events verbose.", verbose_events_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
+       SWITCH_ADD_APP(app_interface, "early_hangup", "Enable early hangup", "", early_hangup_function, "", SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC);
        SWITCH_ADD_APP(app_interface, "sleep", "Pause a channel", SLEEP_LONG_DESC, sleep_function, "<pausemilliseconds>", SAF_SUPPORT_NOMEDIA);
        SWITCH_ADD_APP(app_interface, "delay_echo", "echo audio at a specified delay", "Delay n ms", delay_function, "<delay ms>", SAF_NONE);
        SWITCH_ADD_APP(app_interface, "strftime", "strftime", "strftime", strftime_function, "[<epoch>|]<format string>", SAF_SUPPORT_NOMEDIA);
index 9e5fc7d07450fbe7dfb974c669ce10eed328660b..148d1636d7f0725c649977acfa792ecd89bc8216 100644 (file)
@@ -3833,6 +3833,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
        case nua_callstate_completed:
        case nua_callstate_received:
        case nua_callstate_proceeding:
+       case nua_callstate_completing:
                if (!(session && channel && tech_pvt)) goto done;
                break;
        default:
@@ -3890,9 +3891,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                break;
        case nua_callstate_completing:
                nua_ack(nh,
-                               TAG_IF(tech_pvt && !zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
+                               TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
                                TAG_END());
-               break;
+               goto done;
        case nua_callstate_received:
                if (!sofia_test_flag(tech_pvt, TFLAG_SDP)) {
                        if (r_sdp && !sofia_test_flag(tech_pvt, TFLAG_SDP)) {
index d6357973d1fd6f9103ce54b63e9ba04300ef3bbd..5ddc4558582e26d8eff1c1000968c85881b224a3 100644 (file)
@@ -1911,7 +1911,7 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan
 
                switch_core_session_kill_channel(channel->session, SWITCH_SIG_KILL);
                switch_core_session_signal_state_change(channel->session);
-               switch_core_session_hangup_state(channel->session);
+               switch_core_session_hangup_state(channel->session, SWITCH_FALSE);
        }
 
        return channel->state;
index 0dee04d28b62395218ffe0277a7f6a70d5f79745..e10489bf8d75029b1a1f1c314fd61a8691d9f06a 100644 (file)
@@ -1382,6 +1382,8 @@ static void switch_load_core_config(const char *file)
                                        if (tmp > -1 && tmp < 11) {
                                                switch_core_session_ctl(SCSC_DEBUG_LEVEL, &tmp);
                                        }
+                               } else if (!strcasecmp(var, "enable-early-hangup") && switch_true(val)) {
+                                       switch_set_flag((&runtime), SCF_EARLY_HANGUP);
                                } else if (!strcasecmp(var, "colorize-console") && switch_true(val)) {
                                        runtime.colorize_console = SWITCH_TRUE;
                                } else if (!strcasecmp(var, "mailer-app") && !zstr(val)) {
index 917d3855a52d0f52b257cdea3d9518d676c19b48..a088452070b467c0ac9887639ca381775157cb7c 100644 (file)
@@ -329,7 +329,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                                goto done;
                        case CS_HANGUP: /* Deactivate and end the thread */
                                {
-                                       switch_core_session_hangup_state(session);                              
+                                       switch_core_session_hangup_state(session, SWITCH_TRUE);                         
                                        switch_channel_set_state(session->channel, CS_REPORTING);
                                }
 
@@ -437,7 +437,7 @@ SWITCH_DECLARE(void) switch_core_session_destroy_state(switch_core_session_t *se
 }
 
 
-SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session)
+SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *session, switch_bool_t force)
 {
        const char *hook_var;
        switch_core_session_t *use_session = NULL;
@@ -454,15 +454,21 @@ SWITCH_DECLARE(void) switch_core_session_hangup_state(switch_core_session_t *ses
        const switch_state_handler_table_t *driver_state_handler = NULL;
        const switch_state_handler_table_t *application_state_handler = NULL;
 
+       
+       if (!force) {
+               if (!switch_channel_test_flag(session->channel, CF_EARLY_HANGUP) && !switch_test_flag((&runtime), SCF_EARLY_HANGUP)) {
+                       return;
+               }
 
-       if (switch_thread_self() != session->thread_id) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s thread mismatch skipping state handler.\n", 
-                                                 switch_channel_get_name(session->channel));
-               return;
+               if (switch_thread_self() != session->thread_id) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s thread mismatch skipping state handler.\n", 
+                                                         switch_channel_get_name(session->channel));
+                       return;
+               }
        }
 
        if (switch_test_flag(session, SSF_HANGUP)) {
-               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s handler already called, skipping state handler.\n",
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "%s handler already called, skipping state handler.\n",
                                                  switch_channel_get_name(session->channel));
                return;
        }
index 009e74240477c618399a4416355cc443fe693bec..df229cbc570fcf146a11fb236e1782b204946b2b 100644 (file)
@@ -569,7 +569,7 @@ SWITCH_DECLARE(void) CoreSession::hangupState(void)
        sanity_check_noreturn;  
        this->begin_allow_threads();
        if (switch_channel_down(channel)) {
-               switch_core_session_hangup_state(session);
+               switch_core_session_hangup_state(session, SWITCH_FALSE);
        }
        this->end_allow_threads();
 }