From bb693102599a782db9acac37cd0bdf8cc4a1c411 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 15 Aug 2012 22:51:31 -0500 Subject: [PATCH] FS-4079 FS-4540 please update to this version --- libs/sofia-sip/.update | 2 +- .../libsofia-sip-ua/nua/nua_session.c | 6 +- src/include/private/switch_core_pvt.h | 3 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 + src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 112 +++++++++++++----- src/switch_channel.c | 7 +- src/switch_core_memory.c | 38 +++--- src/switch_core_session.c | 8 ++ src/switch_core_state_machine.c | 2 +- 10 files changed, 134 insertions(+), 50 deletions(-) diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update index 9521702c60..142a1e1a97 100644 --- a/libs/sofia-sip/.update +++ b/libs/sofia-sip/.update @@ -1 +1 @@ -Wed Jul 18 21:45:15 CDT 2012 +Wed Aug 15 22:51:21 CDT 2012 diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c index 751b1cfff8..c17b7b9bb0 100644 --- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c +++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_session.c @@ -2147,7 +2147,7 @@ nua_session_server_init(nua_server_request_t *sr) if (request->sip_multipart) { mp = request->sip_multipart; } else { - mp = msg_multipart_parse(msg_home(msg), + mp = msg_multipart_parse(nua_handle_home(nh), request->sip_content_type, (sip_payload_t *)request->sip_payload); request->sip_multipart = mp; @@ -2162,13 +2162,13 @@ nua_session_server_init(nua_server_request_t *sr) mpp->mp_payload && mpp->mp_payload->pl_data && su_casenmatch(mpp->mp_content_type->c_type, "application/sdp", 15)) { - request->sip_content_type = msg_content_type_dup(msg_home(msg), mpp->mp_content_type); + request->sip_content_type = msg_content_type_dup(nua_handle_home(nh), mpp->mp_content_type); if (request->sip_content_length) { request->sip_content_length->l_length = mpp->mp_payload->pl_len; } - request->sip_payload->pl_data = su_strdup(msg_home(msg), mpp->mp_payload->pl_data); + request->sip_payload->pl_data = su_strdup(nua_handle_home(nh), mpp->mp_payload->pl_data); request->sip_payload->pl_len = mpp->mp_payload->pl_len; sdp++; diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 6d36bae008..2df37b0e05 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -98,7 +98,8 @@ typedef enum { SSF_READ_TRANSCODE = (1 << 5), SSF_WRITE_TRANSCODE = (1 << 6), SSF_READ_CODEC_RESET = (1 << 7), - SSF_WRITE_CODEC_RESET = (1 << 8) + SSF_WRITE_CODEC_RESET = (1 << 8), + SSF_DESTROYABLE = (1 << 9) } switch_session_flag_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 650b898399..5cb9108597 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -429,6 +429,10 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) gateway_ptr = sofia_reg_find_gateway(gateway_name); } + if (!tech_pvt) { + return SWITCH_STATUS_SUCCESS; + } + switch_mutex_lock(tech_pvt->sofia_mutex); rec = sofia_test_flag(tech_pvt, TFLAG_RECOVERING); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 6d01de8a38..472b327ea8 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -154,6 +154,7 @@ typedef struct sofia_dispatch_event_s { int save; switch_core_session_t *session; switch_memory_pool_t *pool; + struct sofia_dispatch_event_s *next; } sofia_dispatch_event_t; struct sofia_private { @@ -166,6 +167,7 @@ struct sofia_private { int is_call; int is_static; sofia_dispatch_event_t *de; + sofia_dispatch_event_t *deq; }; #define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);} diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 58a658e9ea..bd1c0a88a8 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -969,18 +969,25 @@ static void our_sofia_event_callback(nua_event_t event, int locked = 0; int check_destroy = 1; - if (sofia_private && sofia_private->is_call && sofia_private->de) { - sofia_dispatch_event_t *qde = sofia_private->de; - sofia_private->de = NULL; + if (sofia_private && sofia_private->is_call) { + sofia_dispatch_event_t *qde = NULL; - if (event == nua_i_cancel) { - nua_destroy_event(qde->event); - su_free(nh->nh_home, qde); - } else { + switch_mutex_lock(profile->flag_mutex); + if (sofia_private->de) { + qde = sofia_private->de; + sofia_private->de = NULL; + } + switch_mutex_unlock(profile->flag_mutex); + + if (qde) { sofia_process_dispatch_event(&qde); } } + if (sofia_private && (sofia_private->destroy_me == 12)) { + return; + } + profile->last_sip_event = switch_time_now(); /* sofia_private will be == &mod_sofia_globals.keep_private whenever a request is done with a new handle that has to be @@ -1525,22 +1532,51 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) { - sofia_dispatch_event_t *de = *dep; + sofia_dispatch_event_t *de = *dep, *deq = NULL; nua_handle_t *nh = de->nh; nua_t *nua = de->nua; sofia_profile_t *profile = de->profile; - + sofia_private_t *sofia_private = nua_handle_magic(de->nh); *dep = NULL; our_sofia_event_callback(de->data->e_event, de->data->e_status, de->data->e_phrase, de->nua, de->profile, - de->nh, nua_handle_magic(de->nh), de->sip, de, (tagi_t *) de->data->e_tags); + de->nh, sofia_private, de->sip, de, (tagi_t *) de->data->e_tags); nua_destroy_event(de->event); su_free(nh->nh_home, de); switch_mutex_lock(profile->flag_mutex); profile->queued_events--; + if (sofia_private && sofia_private->is_call && sofia_private->deq) { + deq = sofia_private->deq; + sofia_private->deq = NULL; + } switch_mutex_unlock(profile->flag_mutex); + + if (deq) { + for (;;) { + switch_mutex_lock(profile->flag_mutex); + if ((de = deq)) { + deq = deq->next; + de->next = NULL; + } + switch_mutex_unlock(profile->flag_mutex); + + if (!de) { + break; + } + + our_sofia_event_callback(de->data->e_event, de->data->e_status, de->data->e_phrase, de->nua, de->profile, + de->nh, sofia_private, de->sip, de, (tagi_t *) de->data->e_tags); + + nua_destroy_event(de->event); + su_free(nh->nh_home, de); + nua_handle_unref(nh); + nua_stack_unref(nua); + + } + } + nua_handle_unref(nh); nua_stack_unref(nua); @@ -1684,8 +1720,6 @@ void sofia_event_callback(nua_event_t event, return; } - - switch_mutex_lock(profile->flag_mutex); profile->queued_events++; switch_mutex_unlock(profile->flag_mutex); @@ -1707,7 +1741,9 @@ void sofia_event_callback(nua_event_t event, memset(sofia_private, 0, sizeof(*sofia_private)); sofia_private->is_call++; sofia_private->is_static++; + switch_mutex_lock(profile->flag_mutex); sofia_private->de = de; + switch_mutex_unlock(profile->flag_mutex); nua_handle_bind(nh, sofia_private); return; } @@ -1715,7 +1751,23 @@ void sofia_event_callback(nua_event_t event, if (sofia_private && sofia_private != &mod_sofia_globals.destroy_private && sofia_private != &mod_sofia_globals.keep_private) { switch_core_session_t *session; - if (!zstr(sofia_private->uuid)) { + if (zstr(sofia_private->uuid)) { + if (sofia_private->is_call && !sofia_private->de) { + sofia_dispatch_event_t *dep; + + switch_mutex_lock(profile->flag_mutex); + + if (!sofia_private->deq) { + sofia_private->deq = de; + } else { + for (dep = sofia_private->deq; dep && dep->next; dep = dep->next); + dep->next = de; + } + + switch_mutex_unlock(profile->flag_mutex); + return; + } + } else { if ((session = switch_core_session_locate(sofia_private->uuid))) { if (switch_core_session_running(session)) { switch_core_session_queue_signal_data(session, de); @@ -1732,7 +1784,7 @@ void sofia_event_callback(nua_event_t event, } } } - + sofia_queue_message(de); switch_os_yield(); } @@ -6040,9 +6092,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, } } - if (sofia_private) { - sofia_private->destroy_me = 1; - } + // if (sofia_private) { + //sofia_private->destroy_me = 1; + //} } if (session) { @@ -8013,6 +8065,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ profile->ib_calls++; + if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING)) { nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END()); goto fail; @@ -8217,14 +8270,8 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END()); goto fail; } - - if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); - nua_respond(nh, SIP_503_SERVICE_UNAVAILABLE, TAG_END()); - switch_core_session_destroy(&session); - goto fail; - } - + + tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)); switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); @@ -9031,6 +9078,10 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ } switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid)); + if (switch_core_session_running(session) || switch_core_session_started(session)) { + return; + } + if (sip && switch_core_session_thread_launch(session) == SWITCH_STATUS_SUCCESS) { const char *dialog_from_user = "", *dialog_from_host = "", *to_user = "", *to_host = "", *contact_user = "", *contact_host = ""; const char *user_agent = "", *call_id = ""; @@ -9119,6 +9170,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting NAT mode based on %s\n", is_nat); switch_channel_set_variable(channel, "sip_nat_detected", "true"); } + return; } @@ -9140,10 +9192,12 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ switch_mutex_unlock(tech_pvt->profile->flag_mutex); } - 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()); + if (!switch_core_session_running(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()); + } return; fail: diff --git a/src/switch_channel.c b/src/switch_channel.c index a8f05f1928..2a3a7ad04f 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -576,10 +576,15 @@ SWITCH_DECLARE(void) switch_channel_uninit(switch_channel_t *channel) while (switch_queue_trypop(channel->dtmf_log_queue, &pop) == SWITCH_STATUS_SUCCESS) { switch_safe_free(pop); } - switch_core_hash_destroy(&channel->private_hash); + + if (channel->private_hash) { + switch_core_hash_destroy(&channel->private_hash); + } + if (channel->app_flag_hash) { switch_core_hash_destroy(&channel->app_flag_hash); } + switch_mutex_lock(channel->profile_mutex); switch_event_destroy(&channel->variables); switch_event_destroy(&channel->api_list); diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 38a066b020..aedceaf435 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -80,8 +80,8 @@ SWITCH_DECLARE(void *) switch_core_perform_session_alloc(switch_core_session_t * #ifdef DEBUG_ALLOC if (memory > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Session Allocate %s %d\n", - apr_pool_tag(session->pool, NULL), (int) memory); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p %p Session Allocate %s %d\n", + (void *) session->pool, (void *) session, apr_pool_tag(session->pool, NULL), (int) memory); #endif ptr = apr_palloc(session->pool, memory); @@ -113,8 +113,8 @@ SWITCH_DECLARE(void *) switch_core_perform_permanent_alloc(switch_size_t memory, #endif #ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %s %d\n", - apr_pool_tag(memory_manager.memory_pool, NULL), (int) memory); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Perm Allocate %s %d\n", + (void *)memory_manager.memory_pool, apr_pool_tag(memory_manager.memory_pool, NULL), (int) memory); #endif ptr = apr_palloc(memory_manager.memory_pool, memory); @@ -155,8 +155,8 @@ SWITCH_DECLARE(char *) switch_core_perform_permanent_strdup(const char *todup, c switch_assert(duped != NULL); #ifdef DEBUG_ALLOC - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %s %d\n", - apr_pool_tag(memory_manager.memory_pool, NULL), (int) len); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Perm Allocate %s %d\n", + (void *) memory_manager.memory_pool, apr_pool_tag(memory_manager.memory_pool, NULL), (int) len); #endif #ifdef LOCK_MORE @@ -248,8 +248,8 @@ SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t #ifdef DEBUG_ALLOC len = strlen(todup); if (len > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Sess Strdup Allocate %s %ld\n", - apr_pool_tag(session->pool, NULL), strlen(todup)); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p %p Sess Strdup Allocate %s %ld\n", + (void *) session->pool, (void *)session, apr_pool_tag(session->pool, NULL), strlen(todup)); #endif duped = apr_pstrdup(session->pool, todup); @@ -287,8 +287,8 @@ SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, co #ifdef DEBUG_ALLOC if (len > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Strdup Allocate %s %d\n", - apr_pool_tag(pool, NULL), (int)len); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Strdup Allocate %s %d\n", + (void *) pool, apr_pool_tag(pool, NULL), (int)len); #endif duped = apr_pstrmemdup(pool, todup, len); @@ -400,7 +400,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memor apr_pool_tag(*pool, tmp); #ifdef DEBUG_ALLOC2 - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "New Pool %s\n", apr_pool_tag(*pool, NULL)); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p New Pool %s\n", (void *) *pool, apr_pool_tag(*pool, NULL)); #endif @@ -416,7 +416,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_m switch_assert(pool != NULL); #ifdef DEBUG_ALLOC2 - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Free Pool %s\n", apr_pool_tag(*pool, NULL)); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Free Pool %s\n", (void *) *pool, apr_pool_tag(*pool, NULL)); #endif #ifdef INSTANTLY_DESTROY_POOLS @@ -458,8 +458,8 @@ SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, swi #ifdef DEBUG_ALLOC if (memory > 500) - switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Allocate %s %d\n", - apr_pool_tag(pool, NULL), (int) memory); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p Core Allocate %s %d\n", + (void *) pool, apr_pool_tag(pool, NULL), (int) memory); /*switch_assert(memory < 20000); */ #endif @@ -525,16 +525,26 @@ static void *SWITCH_THREAD_FUNC pool_thread(switch_thread_t *thread, void *obj) #ifdef USE_MEM_LOCK switch_mutex_lock(memory_manager.mem_lock); #endif + +#ifdef DEBUG_ALLOC + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%p DESTROY POOL\n", (void *) pop); +#endif apr_pool_destroy(pop); #ifdef USE_MEM_LOCK switch_mutex_unlock(memory_manager.mem_lock); #endif #else apr_pool_mutex_set(pop, NULL); +#ifdef DEBUG_ALLOC + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%p DESTROY POOL\n", (void *) pop); +#endif apr_pool_clear(pop); if (switch_queue_trypush(memory_manager.pool_recycle_queue, pop) != SWITCH_STATUS_SUCCESS) { #ifdef USE_MEM_LOCK switch_mutex_lock(memory_manager.mem_lock); +#endif +#ifdef DEBUG_ALLOC + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%p DESTROY POOL\n", (void *) pop); #endif apr_pool_destroy(pop); #ifdef USE_MEM_LOCK diff --git a/src/switch_core_session.c b/src/switch_core_session.c index e3262899a6..4113afd1e0 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1260,6 +1260,11 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t * switch_endpoint_interface_t *endpoint_interface = (*session)->endpoint_interface; int i; + if (switch_core_session_running(*session) && !switch_test_flag((*session), SSF_DESTROYABLE)) { + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(*session), SWITCH_LOG_ERROR, + "Cowardly ignoring an attempt to call destroy on a running session.\n"); + } + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_core_session_get_uuid(*session), SWITCH_LOG_NOTICE, "Close Channel %s [%s]\n", switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel))); @@ -1440,6 +1445,8 @@ static void *SWITCH_THREAD_FUNC switch_core_session_thread(switch_thread_t *thre switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Session %" SWITCH_SIZE_T_FMT " (%s) Ended\n", session->id, switch_channel_get_name(session->channel)); + + switch_set_flag(session, SSF_DESTROYABLE); switch_core_session_destroy(&session); return NULL; } @@ -1454,6 +1461,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(switch_core_se switch_threadattr_detach_set(thd_attr, 1); if (switch_test_flag(session, SSF_THREAD_RUNNING) || switch_test_flag(session, SSF_THREAD_STARTED)) { + status = SWITCH_STATUS_INUSE; goto end; } diff --git a/src/switch_core_state_machine.c b/src/switch_core_state_machine.c index e567daa9fb..46d49e6883 100644 --- a/src/switch_core_state_machine.c +++ b/src/switch_core_state_machine.c @@ -336,7 +336,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 = 60000; + uint32_t new_loops = 5000; /* Life of the channel. you have channel and pool in your session