From 2fefaaaccc89fc31e878906c72971015fcd56a1d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 19 Nov 2008 19:22:20 +0000 Subject: [PATCH] clean up some ref counting for interfaces git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10464 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_module_interfaces.h | 18 ++++++++++++++++-- .../applications/mod_dptools/mod_dptools.c | 4 ---- src/switch_core_session.c | 11 +++++++++-- src/switch_loadable_module.c | 19 ++++++++++--------- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 3cb497975a..238825d328 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -173,6 +173,7 @@ struct switch_endpoint_interface { switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; /* parent */ switch_loadable_module_interface_t *parent; @@ -228,6 +229,7 @@ struct switch_timer_interface { switch_status_t (*timer_destroy) (switch_timer_t *); switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_timer_interface *next; }; @@ -240,6 +242,7 @@ struct switch_dialplan_interface { switch_dialplan_hunt_function_t hunt_function; switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_dialplan_interface *next; }; @@ -266,6 +269,7 @@ struct switch_file_interface { char **extens; switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_file_interface *next; }; @@ -345,6 +349,7 @@ struct switch_asr_interface { switch_status_t (*asr_get_results) (switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags); switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_asr_interface *next; }; @@ -388,6 +393,7 @@ struct switch_speech_interface { void (*speech_float_param_tts) (switch_speech_handle_t *sh, char *param, double val); switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_speech_interface *next; }; @@ -423,6 +429,7 @@ struct switch_say_interface { switch_say_callback_t say_function; switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_say_interface *next; }; @@ -435,6 +442,7 @@ struct switch_chat_interface { switch_status_t (*chat_send) (char *proto, char *from, char *to, char *subject, char *body, char *hint); switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_chat_interface *next; }; @@ -447,6 +455,7 @@ struct switch_management_interface { switch_status_t (*management_function) (char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen); switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_management_interface *next; }; @@ -467,6 +476,7 @@ struct switch_directory_interface { switch_status_t (*directory_next_pair) (switch_directory_handle_t *dh, char **var, char **val); switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_directory_interface *next; }; @@ -593,6 +603,7 @@ struct switch_codec_interface { uint32_t codec_id; switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_codec_interface *next; }; @@ -613,6 +624,7 @@ struct switch_application_interface { uint32_t flags; switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_application_interface *next; }; @@ -629,12 +641,14 @@ struct switch_api_interface { const char *syntax; switch_thread_rwlock_t *rwlock; int refs; + switch_mutex_t *reflock; switch_loadable_module_interface_t *parent; struct switch_api_interface *next; }; -#define PROTECT_INTERFACE(_it) if (_it && !_it->refs) {switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++;} //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK\n"); -#define UNPROTECT_INTERFACE(_it) if (_it && _it->refs) {switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; _it = NULL;} //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "-----------UNLOCK\n"); +#define PROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock); _it->refs++; _it->parent->refs++; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "+++++++++++LOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); +#define UNPROTECT_INTERFACE(_it) if (_it) {switch_mutex_lock(_it->reflock); switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it->refs--; _it->parent->refs--; switch_mutex_unlock(_it->reflock);} //if (!strcmp(_it->interface_name, "user")) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "---------UNLOCK %s %d/%d\n", _it->interface_name, _it->refs, _it->parent->refs); + SWITCH_END_EXTERN_C #endif diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index e042ba6df0..5a6436b2ad 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1964,8 +1964,6 @@ static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } - UNPROTECT_INTERFACE(error_endpoint_interface); - return cause; } @@ -2126,8 +2124,6 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, done: - UNPROTECT_INTERFACE(user_endpoint_interface); - if (xml) { switch_xml_free(xml); } diff --git a/src/switch_core_session.c b/src/switch_core_session.c index ad359ca34b..74db526b6c 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -242,7 +242,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ { switch_io_event_hook_outgoing_channel_t *ptr; switch_status_t status = SWITCH_STATUS_FALSE; - const switch_endpoint_interface_t *endpoint_interface; + switch_endpoint_interface_t *endpoint_interface; switch_channel_t *channel = NULL; switch_caller_profile_t *outgoing_profile = caller_profile; switch_call_cause_t cause = SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL; @@ -301,6 +301,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ if ((cause = endpoint_interface->io_routines->outgoing_channel(session, var_event, outgoing_profile, new_session, pool, flags)) != SWITCH_CAUSE_SUCCESS) { + UNPROTECT_INTERFACE(endpoint_interface); return cause; } @@ -315,6 +316,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ if (!*new_session) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Outgoing method for endpoint: [%s] returned: [%s] but there is no new session!\n", endpoint_name, switch_channel_cause2str(cause)); + UNPROTECT_INTERFACE(endpoint_interface); return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; } else { switch_caller_profile_t *profile = NULL, *peer_profile = NULL, *cloned_profile = NULL; @@ -414,6 +416,7 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_ } } + UNPROTECT_INTERFACE(endpoint_interface); return cause; } @@ -1111,14 +1114,18 @@ SWITCH_DECLARE(switch_size_t) switch_core_session_id(void) SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_by_name(const char *endpoint_name, switch_memory_pool_t **pool) { switch_endpoint_interface_t *endpoint_interface; + switch_core_session_t *session; if ((endpoint_interface = switch_loadable_module_get_endpoint_interface(endpoint_name)) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not locate channel type %s\n", endpoint_name); return NULL; } - return switch_core_session_request(endpoint_interface, pool); + session = switch_core_session_request(endpoint_interface, pool); + UNPROTECT_INTERFACE(endpoint_interface); + + return session; } #ifndef SWITCH_PREFIX_DIR diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 77a5ba26ba..9aabce4843 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -428,7 +428,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Endpoint '%s'\n", ptr->interface_name); @@ -513,7 +513,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) { @@ -540,7 +540,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } @@ -568,7 +568,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } for (i = 0; ptr->extens[i]; i++) { @@ -596,7 +596,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Speech interface '%s'\n", ptr->interface_name); @@ -621,7 +621,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Asr interface '%s'\n", ptr->interface_name); @@ -646,7 +646,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Directory interface '%s'\n", ptr->interface_name); @@ -671,7 +671,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Chat interface '%s'\n", ptr->interface_name); @@ -695,7 +695,7 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t 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_ERROR, "Giving up on '%s' waiting for existing references.\n", ptr->interface_name); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting Say interface '%s'\n", ptr->interface_name); if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) { @@ -1567,6 +1567,7 @@ SWITCH_DECLARE(switch_loadable_module_interface_t *) switch_loadable_module_crea mod->_TYPE_##_interface = i; \ } \ switch_thread_rwlock_create(&i->rwlock, mod->pool); \ + switch_mutex_init(&i->reflock, SWITCH_MUTEX_NESTED, mod->pool); \ i->parent = mod; \ return i; }