From c8b8672a3ea3dd20f647bd5cbd676c45e454a318 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 9 Sep 2008 15:25:31 +0000 Subject: [PATCH] still try to graceful shutdown in dire cirumstances git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9490 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_apr.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 6 +++++- src/switch_apr.c | 16 ++++++++++++++++ src/switch_loadable_module.c | 26 ++++++++++++++++++-------- 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index 81b7207879..26d8a9c13e 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -397,6 +397,7 @@ SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_rdlock(switch_thread_rwlock SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_tryrdlock(switch_thread_rwlock_t *rwlock); SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_wrlock(switch_thread_rwlock_t *rwlock); SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_trywrlock(switch_thread_rwlock_t *rwlock); +SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_trywrlock_timeout(switch_thread_rwlock_t *rwlock, int timeout); SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock); /** @} */ diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index a1c2b75069..38128d508d 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -510,6 +510,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void int use_100rel = !sofia_test_pflag(profile, PFLAG_DISABLE_100REL); int use_timer = !sofia_test_pflag(profile, PFLAG_DISABLE_TIMER); const char *supported = NULL; + int sanity = 4; switch_mutex_lock(mod_sofia_globals.mutex); mod_sofia_globals.threads++; @@ -658,8 +659,11 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void } while (profile->inuse) { - switch_yield(100000); + switch_yield(5000000); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "waiting for %d session(s)\n", profile->inuse); + if (!sanity--) { + break; + } } nua_destroy(profile->nua); diff --git a/src/switch_apr.c b/src/switch_apr.c index f29c81885e..a936b780a0 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -170,6 +170,22 @@ SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_trywrlock(switch_thread_rwl return apr_thread_rwlock_trywrlock(rwlock); } +SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_trywrlock_timeout(switch_thread_rwlock_t *rwlock, int timeout) +{ + int sanity = timeout * 2; + + while (sanity) { + if (switch_thread_rwlock_trywrlock(rwlock) == SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_SUCCESS; + } + sanity--; + switch_yield(500000); + } + + return SWITCH_STATUS_FALSE; +} + + SWITCH_DECLARE(switch_status_t) switch_thread_rwlock_unlock(switch_thread_rwlock_t *rwlock) { return apr_thread_rwlock_unlock(rwlock); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index b93bfb8226..d75b58df81 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -424,9 +424,11 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t switch_core_session_hupall_endpoint(ptr, SWITCH_CAUSE_SYSTEM_SHUTDOWN); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n", ptr->interface_name); - switch_thread_rwlock_wrlock(ptr->rwlock); - switch_thread_rwlock_unlock(ptr->rwlock); - + if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) { + switch_thread_rwlock_unlock(ptr->rwlock); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up waiting for existing references.\n"); + } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name); switch_core_hash_delete(loadable_modules.endpoint_hash, ptr->interface_name); @@ -505,9 +507,12 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Application '%s'\n", ptr->interface_name); switch_core_session_hupall_matching_var(SWITCH_CURRENT_APPLICATION_VARIABLE, ptr->interface_name, SWITCH_CAUSE_SYSTEM_SHUTDOWN); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n", ptr->interface_name); - switch_thread_rwlock_wrlock(ptr->rwlock); - switch_thread_rwlock_unlock(ptr->rwlock); - + if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) { + switch_thread_rwlock_unlock(ptr->rwlock); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up waiting for existing references.\n"); + } + if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "application"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "name", ptr->interface_name); @@ -528,8 +533,13 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting API Function '%s'\n", ptr->interface_name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n", ptr->interface_name); - switch_thread_rwlock_wrlock(ptr->rwlock); - switch_thread_rwlock_unlock(ptr->rwlock); + + if (switch_thread_rwlock_trywrlock_timeout(ptr->rwlock, 10) == SWITCH_STATUS_SUCCESS) { + switch_thread_rwlock_unlock(ptr->rwlock); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Giving up waiting for existing references.\n"); + } + if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "api");