From 8423f28d431cd01c96bca2cae0b2ee44a3ae9e26 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Feb 2016 16:22:46 -0600 Subject: [PATCH] FS-8841 #resolve [Debian - FS Hang ] --- src/mod/endpoints/mod_sofia/mod_sofia.c | 23 +++-- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 + src/mod/endpoints/mod_sofia/sofia.c | 106 ++++++++++++++--------- src/mod/endpoints/mod_sofia/sofia_glue.c | 6 -- 4 files changed, 83 insertions(+), 54 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 9f5cd56af7..c4a38559b4 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -5008,7 +5008,7 @@ static int notify_callback(void *pArg, int argc, char **argv, char **columnNames return 0; } -static void general_event_handler(switch_event_t *event) +void general_event_handler(switch_event_t *event) { switch (event->event_id) { case SWITCH_EVENT_NOTIFY: @@ -5546,6 +5546,14 @@ static void general_event_handler(switch_event_t *event) } } +static void general_queue_event_handler(switch_event_t *event) +{ + switch_event_t *dup; + switch_event_dup(&dup, event); + switch_queue_push(mod_sofia_globals.general_event_queue, dup); +} + + void write_csta_xml_chunk(switch_event_t *event, switch_stream_handle_t stream, const char *csta_event, char *fwdtype) { const char *device = switch_event_get_header(event, "device"); @@ -5882,6 +5890,7 @@ 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.general_event_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; @@ -5952,27 +5961,27 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) return SWITCH_STATUS_GENERR; } - if (switch_event_bind(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_event_bind(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; } - if (switch_event_bind(modname, SWITCH_EVENT_NOTIFY, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_event_bind(modname, SWITCH_EVENT_NOTIFY, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; } - if (switch_event_bind(modname, SWITCH_EVENT_PHONE_FEATURE, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_event_bind(modname, SWITCH_EVENT_PHONE_FEATURE, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; } - if (switch_event_bind(modname, SWITCH_EVENT_SEND_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_event_bind(modname, SWITCH_EVENT_SEND_MESSAGE, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; } - if (switch_event_bind(modname, SWITCH_EVENT_SEND_INFO, SWITCH_EVENT_SUBCLASS_ANY, general_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { + if (switch_event_bind(modname, SWITCH_EVENT_SEND_INFO, SWITCH_EVENT_SUBCLASS_ANY, general_queue_event_handler, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n"); return SWITCH_STATUS_GENERR; } @@ -6075,7 +6084,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sofia_shutdown) switch_event_unbind_callback(sofia_presence_event_handler); - switch_event_unbind_callback(general_event_handler); + switch_event_unbind_callback(general_queue_event_handler); switch_event_unbind_callback(event_handler); switch_queue_push(mod_sofia_globals.presence_queue, NULL); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 582c69e534..a41e75abee 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -365,6 +365,7 @@ struct mod_sofia_globals { char hostname[512]; switch_queue_t *presence_queue; switch_queue_t *msg_queue; + switch_queue_t *general_event_queue; switch_thread_t *msg_queue_thread[SOFIA_MAX_MSG_QUEUE]; int msg_queue_len; struct sofia_private destroy_private; @@ -1193,6 +1194,7 @@ void sofia_glue_fire_events(sofia_profile_t *profile); void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event); void sofia_queue_message(sofia_dispatch_event_t *de); int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip); +void general_event_handler(switch_event_t *event); switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port, const char *sourceip, switch_memory_pool_t *pool); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index c6032cbd26..1ef255ca1f 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2659,64 +2659,88 @@ void *SWITCH_THREAD_FUNC sofia_profile_worker_thread_run(switch_thread_t *thread uint32_t ireg_loops = profile->ireg_seconds; /* Number of loop iterations done when we haven't checked for registrations */ uint32_t iping_loops = profile->iping_freq; /* Number of loop iterations done when we haven't checked for ping expires */ uint32_t gateway_loops = GATEWAY_SECONDS; /* Number of loop iterations done when we haven't checked for gateways */ + void *pop; + int tick = 0, x = 0; sofia_set_pflag_locked(profile, PFLAG_WORKER_RUNNING); while ((mod_sofia_globals.running == 1 && sofia_test_pflag(profile, PFLAG_RUNNING))) { - if (profile->watchdog_enabled) { - uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0; + if (tick) { + if (profile->watchdog_enabled) { + uint32_t event_diff = 0, step_diff = 0, event_fail = 0, step_fail = 0; - if (profile->step_timeout) { - step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000); + if (profile->step_timeout) { + step_diff = (uint32_t) ((switch_time_now() - profile->last_root_step) / 1000); - if (step_diff > profile->step_timeout) { - step_fail = 1; + if (step_diff > profile->step_timeout) { + step_fail = 1; + } + } + + if (profile->event_timeout) { + event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000); + + if (event_diff > profile->event_timeout) { + event_fail = 1; + } + } + + if (step_fail && profile->event_timeout && !event_fail) { + step_fail = 0; + } + + if (event_fail || step_fail) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n" + "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name); + switch_yield(2000000); + watchdog_triggered_abort(); } } - if (profile->event_timeout) { - event_diff = (uint32_t) ((switch_time_now() - profile->last_sip_event) / 1000); - if (event_diff > profile->event_timeout) { - event_fail = 1; + if (!sofia_test_pflag(profile, PFLAG_STANDBY)) { + if (++ireg_loops >= (uint32_t)profile->ireg_seconds) { + time_t now = switch_epoch_time_now(NULL); + sofia_reg_check_expire(profile, now, 0); + ireg_loops = 0; } - } - - if (step_fail && profile->event_timeout && !event_fail) { - step_fail = 0; - } - - if (event_fail || step_fail) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Profile %s: SIP STACK FAILURE DETECTED BY WATCHDOG!\n" - "GOODBYE CRUEL WORLD, I'M LEAVING YOU TODAY....GOODBYE, GOODBYE, GOOD BYE\n", profile->name); - switch_yield(2000000); - watchdog_triggered_abort(); - } - } - - - if (!sofia_test_pflag(profile, PFLAG_STANDBY)) { - if (++ireg_loops >= (uint32_t)profile->ireg_seconds) { - time_t now = switch_epoch_time_now(NULL); - sofia_reg_check_expire(profile, now, 0); - ireg_loops = 0; - } - if(++iping_loops >= (uint32_t)profile->iping_freq) { - time_t now = switch_epoch_time_now(NULL); - sofia_reg_check_ping_expire(profile, now, profile->iping_seconds); - iping_loops = 0; + if(++iping_loops >= (uint32_t)profile->iping_freq) { + time_t now = switch_epoch_time_now(NULL); + sofia_reg_check_ping_expire(profile, now, profile->iping_seconds); + iping_loops = 0; + } + + if (++gateway_loops >= GATEWAY_SECONDS) { + sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL)); + sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL)); + gateway_loops = 0; + } } - if (++gateway_loops >= GATEWAY_SECONDS) { - sofia_reg_check_gateway(profile, switch_epoch_time_now(NULL)); - sofia_sub_check_gateway(profile, switch_epoch_time_now(NULL)); - gateway_loops = 0; - } + tick = 0; } - switch_yield(1000000); + if (switch_queue_pop_timeout(mod_sofia_globals.general_event_queue, &pop, 100000) == SWITCH_STATUS_SUCCESS) { + + do { + switch_event_t *event = (switch_event_t *) pop; + general_event_handler(event); + switch_event_destroy(&event); + + pop = NULL; + switch_queue_trypop(mod_sofia_globals.general_event_queue, &pop); + } while (pop); + + } + + sofia_glue_fire_events(profile); + + if (++x == 10) { + tick = 1; + x = 0; + } } diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 7dcdfcda79..f4e3396bda 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2476,9 +2476,6 @@ switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile, switch_cache_db_release_db_handle(&dbh); - - sofia_glue_fire_events(profile); - return ret; } @@ -2515,9 +2512,6 @@ char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex switch_cache_db_release_db_handle(&dbh); - - sofia_glue_fire_events(profile); - return ret; }