]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
another efficiency pass on sofia and refactoring of 3c685bff255779d21c1d6cd577276f186...
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 30 Aug 2012 20:26:13 +0000 (15:26 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 30 Aug 2012 20:26:13 +0000 (15:26 -0500)
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_presence.c
src/switch_core_state_machine.c

index 9cb88e4154b88f0c505ba9365a7b2cdb58b0a43e..a471c4339915228344dfd44d63930c618a970c62 100644 (file)
@@ -370,6 +370,7 @@ switch_status_t sofia_on_destroy(switch_core_session_t *session)
 {
        private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
        switch_channel_t *channel = switch_core_session_get_channel(session);
+       char *uuid;
 
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s SOFIA DESTROY\n", switch_channel_get_name(channel));
 
@@ -379,6 +380,15 @@ switch_status_t sofia_on_destroy(switch_core_session_t *session)
                        switch_yield(100000);
                }
 
+               switch_mutex_lock(tech_pvt->profile->flag_mutex);
+               if ((uuid = switch_core_hash_find(tech_pvt->profile->chat_hash, tech_pvt->call_id))) {
+                       free(uuid);
+                       uuid = NULL;
+                       switch_core_hash_delete(tech_pvt->profile->chat_hash, tech_pvt->call_id);
+               }
+               switch_mutex_unlock(tech_pvt->profile->flag_mutex);
+
+
                if (switch_core_codec_ready(&tech_pvt->read_codec)) {
                        switch_core_codec_destroy(&tech_pvt->read_codec);
                }
@@ -408,7 +418,7 @@ switch_status_t sofia_on_destroy(switch_core_session_t *session)
                        sofia_profile_destroy(tech_pvt->profile);
                }
        }
-
+       
        return SWITCH_STATUS_SUCCESS;
 
 }
@@ -5524,7 +5534,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
        mod_sofia_globals.auto_nat = (switch_nat_get_type() ? 1 : 0);
 
        switch_queue_create(&mod_sofia_globals.presence_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool);
-       switch_queue_create(&mod_sofia_globals.mwi_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool);
 
        mod_sofia_globals.cpu_count = switch_core_cpu_count();
        mod_sofia_globals.max_msg_queues = (mod_sofia_globals.cpu_count / 2) + 1;
@@ -5584,7 +5593,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
                return SWITCH_STATUS_GENERR;
        }
 
-       if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_mwi_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
+       if (switch_event_bind(modname, SWITCH_EVENT_MESSAGE_WAITING, SWITCH_EVENT_SUBCLASS_ANY, sofia_presence_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
 
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
                return SWITCH_STATUS_GENERR;
@@ -5707,11 +5716,12 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown)
        switch_mutex_unlock(mod_sofia_globals.mutex);
 
        switch_event_unbind_callback(sofia_presence_event_handler);
-       switch_event_unbind_callback(sofia_presence_mwi_event_handler);
 
        switch_event_unbind_callback(general_event_handler);
        switch_event_unbind_callback(event_handler);
 
+       switch_queue_push(mod_sofia_globals.presence_queue, NULL);
+
        while (mod_sofia_globals.threads) {
                switch_cond_next();
                if (++sanity >= 60000) {
index 817ea8506320d7d1b9d472c6ed1cef7a98b31349..bee5792cc7baea33935baa21a589604c084b75a9 100644 (file)
@@ -362,7 +362,6 @@ struct mod_sofia_globals {
        char guess_ip[80];
        char hostname[512];
        switch_queue_t *presence_queue;
-       switch_queue_t *mwi_queue;
        switch_queue_t *msg_queue;
        switch_thread_t *msg_queue_thread[SOFIA_MAX_MSG_QUEUE];
        int msg_queue_len;
@@ -954,7 +953,7 @@ switch_status_t sofia_glue_tech_media(private_object_t *tech_pvt, const char *r_
 char *sofia_reg_find_reg_url(sofia_profile_t *profile, const char *user, const char *host, char *val, switch_size_t len);
 void event_handler(switch_event_t *event);
 void sofia_presence_event_handler(switch_event_t *event);
-void sofia_presence_mwi_event_handler(switch_event_t *event);
+
 
 void sofia_presence_cancel(void);
 switch_status_t config_sofia(int reload, char *profile_name);
index 84d914fcb78da78c8123e052473eae30ed6dee2b..0b1e85e8ae4abeb46faf8d5515b2e26ebc4ef90f 100644 (file)
@@ -1072,7 +1072,6 @@ static void our_sofia_event_callback(nua_event_t event,
        case nua_r_publish:
        case nua_i_error:
        case nua_i_active:
-       case nua_i_terminated:
        case nua_r_set_params:
        case nua_i_prack:
        case nua_r_prack:
@@ -1094,6 +1093,11 @@ static void our_sofia_event_callback(nua_event_t event,
 
                break;
 
+       case nua_i_terminated:
+               if (!session && nh) {
+                       nua_handle_destroy(nh);
+               }
+               break;
        case nua_r_cancel:
                {
                        if (status > 299 && nh) {
@@ -1526,8 +1530,6 @@ void sofia_process_dispatch_event(sofia_dispatch_event_t **dep)
        if (session) {
                switch_ivr_parse_all_signal_data(session);
        }
-
-       switch_os_yield();
 }
 
 
@@ -1565,7 +1567,6 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj
                if (pop) {
                        sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop;
                        sofia_process_dispatch_event(&de);
-                       switch_os_yield();
                } else {
                        break;
                }
@@ -1653,32 +1654,38 @@ void sofia_event_callback(nua_event_t event,
 {
        sofia_dispatch_event_t *de;
        int critical = (((SOFIA_MSG_QUEUE_SIZE * mod_sofia_globals.max_msg_queues) * 900) / 1000);
-
+       int nuke = 0;
        uint32_t sess_count = switch_core_session_count();
        uint32_t sess_max = switch_core_session_limit(0);
 
        switch(event) {
        case nua_i_terminated:
-               if (status > 300 && sofia_private && sofia_private->uuid) {
+        if ((status == 401 || status == 407) && sofia_private && sofia_private->uuid) {
                        switch_core_session_t *session;
 
-                       if ((session = switch_core_session_force_locate(sofia_private->uuid))) {
-                               switch_channel_t *channel = switch_core_session_get_channel(session);
-                               switch_call_cause_t cause;
+                       if ((session = switch_core_session_locate(sofia_private->uuid))) {
+                               private_object_t *tech_pvt = switch_core_session_get_private(session);
 
-                               cause = sofia_glue_sip_cause_to_freeswitch(status);
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "detaching session %s\n", sofia_private->uuid);                         
 
-                               switch_channel_hangup(channel, cause);
+                               tech_pvt->sofia_private = NULL;
+                               tech_pvt->nh = NULL;
+                               sofia_set_flag(tech_pvt, TFLAG_BYE);
+                               switch_mutex_lock(profile->flag_mutex);
+                               switch_core_hash_insert(profile->chat_hash, tech_pvt->call_id, strdup(switch_core_session_get_uuid(session)));
+                               switch_mutex_unlock(profile->flag_mutex);
                                switch_core_session_rwunlock(session);
-
-                               if (status == 401 || status == 407) {
-                                       switch_channel_set_flag(channel, CF_NO_CDR);
-                                       switch_core_session_id_dec();
-                               }
+                       } else {
+                               nuke++;
                        }
+               } else if (!sofia_private || zstr(sofia_private->uuid) || !switch_ivr_uuid_exists(sofia_private->uuid)) {
+                       nuke++;
+               }
 
+               if (nuke) {
+                       nua_handle_destroy(nh);
+                       goto end;
                }
-               break;
        case nua_i_invite:
        case nua_i_register:
        case nua_i_options:
@@ -1722,6 +1729,7 @@ void sofia_event_callback(nua_event_t event,
 
        if (event == nua_i_invite && !sofia_private) {
                switch_core_session_t *session;
+               private_object_t *tech_pvt = NULL;
 
                if (!(sofia_private = su_alloc(nh->nh_home, sizeof(*sofia_private)))) {
                        abort();
@@ -1732,6 +1740,38 @@ void sofia_event_callback(nua_event_t event,
                sofia_private->is_static++;
                nua_handle_bind(nh, sofia_private);
 
+
+               if (sip->sip_call_id && sip->sip_call_id->i_id) {
+                       char *uuid;
+
+                       switch_mutex_lock(profile->flag_mutex);
+                       if ((uuid = (char *) switch_core_hash_find(profile->chat_hash, sip->sip_call_id->i_id))) {
+                               switch_core_hash_delete(profile->chat_hash, sip->sip_call_id->i_id);
+                       }
+                       switch_mutex_unlock(profile->flag_mutex);
+
+                       if (uuid) {
+                               if ((session = switch_core_session_locate(uuid))) {
+                                       tech_pvt = switch_core_session_get_private(session);
+                                       switch_copy_string(sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(sofia_private->uuid));
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Re-attaching to session %s\n", sofia_private->uuid);
+                                       de->init_session = session;
+                                       sofia_clear_flag(tech_pvt, TFLAG_BYE);
+                                       tech_pvt->sofia_private = NULL;
+                                       tech_pvt->nh = NULL;
+                                       switch_core_session_queue_signal_data(session, de);
+                                       switch_core_session_rwunlock(session);
+                                       session = NULL;
+                                       free(uuid);
+                                       uuid = NULL;
+                                       goto end;
+                               } else {
+                                       free(uuid);
+                                       uuid = NULL;
+                               }
+                       }
+               }
+
                if (sofia_test_pflag(profile, PFLAG_CALLID_AS_UUID)) {
                        session = switch_core_session_request_uuid(sofia_endpoint_interface, SWITCH_CALL_DIRECTION_INBOUND, SOF_NONE, NULL, sip->sip_call_id->i_id);
                } else {
@@ -1740,7 +1780,7 @@ void sofia_event_callback(nua_event_t event,
 
                if (session) {
                        const char *channel_name = NULL;
-                       private_object_t *tech_pvt = sofia_glue_new_pvt(session);
+                       tech_pvt = sofia_glue_new_pvt(session);
 
                        if (sip->sip_from) {
                                channel_name = url_set_chanvars(session, sip->sip_from->a_url, sip_from);
@@ -1751,8 +1791,14 @@ void sofia_event_callback(nua_event_t event,
                        if (sip->sip_referred_by) {
                                channel_name = url_set_chanvars(session, sip->sip_referred_by->b_url, sip_referred_by);
                        }
-
+                       
                        sofia_glue_attach_private(session, profile, tech_pvt, channel_name);
+                       
+                       if (!tech_pvt->call_id && sip->sip_call_id && sip->sip_call_id->i_id) {
+                               switch_channel_t *channel = switch_core_session_get_channel(session);
+                               tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id);
+                               switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id);
+                       }
 
                } else {
                        nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
@@ -1769,13 +1815,24 @@ void sofia_event_callback(nua_event_t event,
                        goto end;
                }
 
+               
                if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
+                       char *uuid;
+
                        if (!switch_core_session_running(session) && !switch_core_session_started(session)) {
                                nua_handle_bind(nh, NULL);
                                sofia_private_free(sofia_private);
                                switch_core_session_destroy(&session);
                                nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END());
                        }
+                       switch_mutex_lock(profile->flag_mutex);
+                       if ((uuid = switch_core_hash_find(profile->chat_hash, tech_pvt->call_id))) {
+                               free(uuid);
+                               uuid = NULL;
+                               switch_core_hash_delete(profile->chat_hash, tech_pvt->call_id);
+                       }
+                       switch_mutex_unlock(profile->flag_mutex);
+
                        goto end;
                }
 
@@ -1799,7 +1856,12 @@ void sofia_event_callback(nua_event_t event,
        sofia_queue_message(de);
 
  end:
-       switch_os_yield();
+
+       if (profile->pres_type) {
+               switch_cond_next();
+       }
+
+
        return;
 }
 
@@ -1839,7 +1901,7 @@ void event_handler(switch_event_t *event)
                        switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Message-Account", switch_event_get_header_nil(event, "orig-MWI-Message-Account"));
                        switch_event_add_header_string(pevent, SWITCH_STACK_BOTTOM, "MWI-Voice-Message", switch_event_get_header_nil(event, "orig-MWI-Voice-Message"));
                        /* we cannot use switch_event_fire, or otherwise we'll start an endless loop */
-                       sofia_presence_mwi_event_handler(pevent);
+                       sofia_presence_event_handler(pevent);
                        return;
                } else {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\nCannot inject MWI event\n");
@@ -8086,7 +8148,6 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
        const char *from_tag = "";
        char *sql = NULL;
 
-
        profile->ib_calls++;
 
 
@@ -8631,11 +8692,6 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
                switch_channel_set_flag(channel, CF_ZRTP_PASSTHRU_REQ);
        }
 
-       if (!tech_pvt->call_id && sip->sip_call_id && sip->sip_call_id->i_id) {
-               tech_pvt->call_id = switch_core_session_strdup(session, sip->sip_call_id->i_id);
-               switch_channel_set_variable(channel, "sip_call_id", tech_pvt->call_id);
-       }
-
        if (sip->sip_subject && sip->sip_subject->g_string) {
                switch_channel_set_variable(channel, "sip_subject", sip->sip_subject->g_string);
        }
@@ -9078,10 +9134,9 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia
                switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
        }
 
-
        tech_pvt->sofia_private = sofia_private;
        tech_pvt->nh = nh;
-       
+
        if (profile->pres_type && sofia_test_pflag(profile, PFLAG_IN_DIALOG_CHAT)) {
                sofia_presence_set_chat_hash(tech_pvt, sip);
        }
index 16ac94a6a8310fdb98aff0866b2887716c2d744b..9f2d0d184e96cb94fb008d141e7165d62f929b57 100644 (file)
@@ -1517,38 +1517,28 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
        while (mod_sofia_globals.running == 1) {
                int count = 0;
 
-               if (switch_queue_trypop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+               if (switch_queue_pop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS) {
                        switch_event_t *event = (switch_event_t *) pop;
 
                        if (!pop) {
                                break;
                        }
-                       
-                       if (event->event_id == SWITCH_EVENT_CONFERENCE_DATA) {
+
+                       switch(event->event_id) {
+                       case SWITCH_EVENT_MESSAGE_WAITING:
+                               actual_sofia_presence_mwi_event_handler(event);
+                               break;
+                       case SWITCH_EVENT_CONFERENCE_DATA:
                                conference_data_event_handler(event);
-                       } else {
+                               break;
+                       default:
                                actual_sofia_presence_event_handler(event);
-                       }
-
-                       switch_event_destroy(&event);
-                       count++;
-               }
-
-               if (switch_queue_trypop(mod_sofia_globals.mwi_queue, &pop) == SWITCH_STATUS_SUCCESS) {
-                       switch_event_t *event = (switch_event_t *) pop;
-
-                       if (!pop) {
                                break;
                        }
 
-                       actual_sofia_presence_mwi_event_handler(event);
                        switch_event_destroy(&event);
                        count++;
                }
-
-               if (!count) {
-                       switch_yield(100000);
-               }
        }
 
        while (switch_queue_trypop(mod_sofia_globals.presence_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
@@ -1556,11 +1546,6 @@ void *SWITCH_THREAD_FUNC sofia_presence_event_thread_run(switch_thread_t *thread
                switch_event_destroy(&event);
        }
 
-       while (switch_queue_trypop(mod_sofia_globals.mwi_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
-               switch_event_t *event = (switch_event_t *) pop;
-               switch_event_destroy(&event);
-       }
-
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Event Thread Ended\n");
 
        switch_mutex_lock(mod_sofia_globals.mutex);
@@ -1610,19 +1595,6 @@ void sofia_presence_event_handler(switch_event_t *event)
        }
 }
 
-void sofia_presence_mwi_event_handler(switch_event_t *event)
-{
-       switch_event_t *cloned_event;
-
-       switch_event_dup(&cloned_event, event);
-       switch_assert(cloned_event);
-       switch_queue_push(mod_sofia_globals.mwi_queue, cloned_event);
-
-       if (!EVENT_THREAD_STARTED) {
-               sofia_presence_event_thread_start();
-       }
-}
-
 
 static int sofia_presence_sub_reg_callback(void *pArg, int argc, char **argv, char **columnNames)
 {
index b830a41d6a5ed4c1d965e36e68139dd15b8b8ae5..a3c7079dbbcc781f77040a605a4cfe08777a3dc8 100644 (file)
@@ -349,7 +349,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
        const switch_state_handler_table_t *driver_state_handler = NULL;
        const switch_state_handler_table_t *application_state_handler = NULL;
        int silly = 0;
-       //      uint32_t new_loops = 5000;
+       uint32_t new_loops = 500;
 
        /*
           Life of the channel. you have channel and pool in your session
@@ -481,17 +481,15 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
                endstate = switch_channel_get_state(session->channel);
 
                if (endstate == switch_channel_get_running_state(session->channel)) {
-                       /**
                        if (endstate == CS_NEW) {
-                               switch_cond_next();
+                               switch_yield(20000);
                                switch_ivr_parse_all_events(session);
                                if (!--new_loops) {
-                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s Timeout waiting for next instruction in CS_NEW!\n",
-                                                                         session->uuid_str);
-                                       switch_channel_hangup(session->channel, SWITCH_CAUSE_INVALID_CALL_REFERENCE);
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s %s Abandoned\n",
+                                                                         session->uuid_str, switch_core_session_get_name(session));
+                                       switch_channel_hangup(session->channel, SWITCH_CAUSE_WRONG_CALL_STATE);
                                }
                        } else {
-                       **/
                                switch_ivr_parse_all_events(session);
                                switch_ivr_parse_all_events(session);
 
@@ -505,7 +503,7 @@ SWITCH_DECLARE(void) switch_core_session_run(switch_core_session_t *session)
 
                                switch_ivr_parse_all_events(session);
                                switch_ivr_parse_all_events(session);
-                               //}
+                       }
                }
        }
   done: