[Freeswitch-svn] [commit] r10363 - in freeswitch/trunk/src: . include mod/dialplans/mod_dialplan_asterisk mod/endpoints/mod_sofia mod/formats/mod_local_stream mod/languages/mod_spidermonkey

FreeSWITCH SVN anthm at freeswitch.org
Wed Nov 12 11:28:06 PST 2008


Author: anthm
Date: Wed Nov 12 14:28:05 2008
New Revision: 10363

Log:
look out below....(make current)

Modified:
   freeswitch/trunk/src/include/switch_loadable_module.h
   freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
   freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
   freeswitch/trunk/src/mod/formats/mod_local_stream/mod_local_stream.c
   freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
   freeswitch/trunk/src/switch_core_asr.c
   freeswitch/trunk/src/switch_core_codec.c
   freeswitch/trunk/src/switch_core_directory.c
   freeswitch/trunk/src/switch_core_file.c
   freeswitch/trunk/src/switch_core_session.c
   freeswitch/trunk/src/switch_core_speech.c
   freeswitch/trunk/src/switch_core_state_machine.c
   freeswitch/trunk/src/switch_core_timer.c
   freeswitch/trunk/src/switch_ivr.c
   freeswitch/trunk/src/switch_ivr_menu.c
   freeswitch/trunk/src/switch_ivr_originate.c
   freeswitch/trunk/src/switch_ivr_play_say.c
   freeswitch/trunk/src/switch_loadable_module.c

Modified: freeswitch/trunk/src/include/switch_loadable_module.h
==============================================================================
--- freeswitch/trunk/src/include/switch_loadable_module.h	(original)
+++ freeswitch/trunk/src/include/switch_loadable_module.h	Wed Nov 12 14:28:05 2008
@@ -392,6 +392,11 @@
 	}
 
 
+#define PROTECT_INTERFACE(_it) switch_thread_rwlock_rdlock(_it->parent->rwlock); switch_thread_rwlock_rdlock(_it->rwlock)
+#define UNPROTECT_INTERFACE(_it) switch_thread_rwlock_unlock(_it->rwlock); switch_thread_rwlock_unlock(_it->parent->rwlock); _it = NULL
+
+
+
 SWITCH_END_EXTERN_C
 #endif
 /* For Emacs:

Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c	(original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_asterisk/mod_dialplan_asterisk.c	Wed Nov 12 14:28:05 2008
@@ -39,12 +39,14 @@
 static switch_status_t exec_app(switch_core_session_t *session, char *app, char *arg)
 {
 	const switch_application_interface_t *application_interface;
+	switch_status_t status = SWITCH_STATUS_FALSE;
 
 	if ((application_interface = switch_loadable_module_get_application_interface(app))) {
-		return switch_core_session_exec(session, application_interface, arg);
+		status = switch_core_session_exec(session, application_interface, arg);
+		UNPROTECT_INTERFACE(application_interface);
 	}
 
-	return SWITCH_STATUS_FALSE;
+	return status;
 }
 
 SWITCH_STANDARD_APP(dial_function)

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c	Wed Nov 12 14:28:05 2008
@@ -1168,9 +1168,9 @@
 						} else if (!strcasecmp(val, "contact") || switch_true(val)) {
 							profile->pflags |= PFLAG_MULTIREG;
 							profile->pflags |= PFLAG_MULTIREG_CONTACT;
-						} else {
+						} else if (switch_true(val)) {
 							profile->pflags &= ~PFLAG_MULTIREG;
-							profile->pflags &= ~PFLAG_MULTIREG_CONTACT;
+							//profile->pflags &= ~PFLAG_MULTIREG_CONTACT;
 						}
 					} else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) {
 						if (switch_true(val)) {
@@ -1629,9 +1629,9 @@
 						} else if (!strcasecmp(val, "contact") || switch_true(val)) {
 							profile->pflags |= PFLAG_MULTIREG;
 							profile->pflags |= PFLAG_MULTIREG_CONTACT;
-						} else {
+						} else if (switch_true(val)) {
 							profile->pflags &= ~PFLAG_MULTIREG;
-							profile->pflags &= ~PFLAG_MULTIREG_CONTACT;
+							//profile->pflags &= ~PFLAG_MULTIREG_CONTACT;
 						}
 					} else if (!strcasecmp(var, "supress-cng") || !strcasecmp(var, "suppress-cng")) {
 						if (switch_true(val)) {

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c	Wed Nov 12 14:28:05 2008
@@ -2865,10 +2865,15 @@
 
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", profile->odbc_dsn);
 		
-		if (switch_odbc_handle_exec(profile->master_odbc, "select hostname from sip_registrations", NULL) != SWITCH_ODBC_SUCCESS) {
+		test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
+								  "or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q'", 
+								  mod_sofia_globals.hostname);
+
+		if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) {
 			switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_registrations", NULL);
 			switch_odbc_handle_exec(profile->master_odbc, reg_sql, NULL);
 		}
+		free(test_sql);
 
 
 		test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q'", mod_sofia_globals.hostname);
@@ -2898,13 +2903,18 @@
 #else
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
 #endif
-	} else {
+	} else {		
 		if (!(profile->master_db = switch_core_db_open_file(profile->dbname))) {
 			return 0;
 		}
 
-		switch_core_db_test_reactive(profile->master_db, "select hostname from sip_registrations", "DROP TABLE sip_registrations", reg_sql);
+		test_sql = switch_mprintf("delete from sip_registrations where (contact like '%%TCP%%' "
+								  "or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q'", 
+								  mod_sofia_globals.hostname);
 		
+		switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_registrations", reg_sql);
+		free(test_sql);
+
 		test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q'", mod_sofia_globals.hostname);
 		switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_subscriptions", sub_sql);
 		free(test_sql);

Modified: freeswitch/trunk/src/mod/formats/mod_local_stream/mod_local_stream.c
==============================================================================
--- freeswitch/trunk/src/mod/formats/mod_local_stream/mod_local_stream.c	(original)
+++ freeswitch/trunk/src/mod/formats/mod_local_stream/mod_local_stream.c	Wed Nov 12 14:28:05 2008
@@ -249,6 +249,11 @@
 	}
 
  done:
+
+	if (fh.file_interface) {
+		switch_core_file_close(&fh);
+	}
+
 	source->ready = 0;
 	switch_mutex_lock(globals.mutex);
 	switch_core_hash_delete(globals.source_hash, source->name);

Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c	(original)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c	Wed Nov 12 14:28:05 2008
@@ -2222,6 +2222,7 @@
 				check_hangup_hook(jss, &ret);
 				retval = JS_TRUE;
 			}
+			UNPROTECT_INTERFACE(application_interface);
 		}
 	}
 

Modified: freeswitch/trunk/src/switch_core_asr.c
==============================================================================
--- freeswitch/trunk/src/switch_core_asr.c	(original)
+++ freeswitch/trunk/src/switch_core_asr.c	Wed Nov 12 14:28:05 2008
@@ -64,6 +64,7 @@
 		ah->memory_pool = pool;
 	} else {
 		if ((status = switch_core_new_memory_pool(&ah->memory_pool)) != SWITCH_STATUS_SUCCESS) {
+			UNPROTECT_INTERFACE(ah->asr_interface);
 			return status;
 		}
 		switch_set_flag(ah, SWITCH_ASR_FLAG_FREE_POOL);
@@ -127,6 +128,7 @@
 	switch_assert(ah != NULL);
 
 	status = ah->asr_interface->asr_close(ah, flags);
+	UNPROTECT_INTERFACE(ah->asr_interface);
 
 	if (switch_test_flag(ah, SWITCH_ASR_FLAG_FREE_POOL)) {
 		switch_core_destroy_memory_pool(&ah->memory_pool);

Modified: freeswitch/trunk/src/switch_core_codec.c
==============================================================================
--- freeswitch/trunk/src/switch_core_codec.c	(original)
+++ freeswitch/trunk/src/switch_core_codec.c	Wed Nov 12 14:28:05 2008
@@ -451,12 +451,15 @@
 
 		implementation->init(codec, flags, codec_settings);
 		switch_mutex_init(&codec->mutex, SWITCH_MUTEX_NESTED, codec->memory_pool);
+		
 		return SWITCH_STATUS_SUCCESS;
 	} else {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Codec %s Exists but not at the desired implementation. %dhz %dms\n", codec_name, rate,
 						  ms);
 	}
 
+	UNPROTECT_INTERFACE(codec_interface);
+
 	return SWITCH_STATUS_NOTIMPL;
 }
 
@@ -541,6 +544,9 @@
 	if (mutex) switch_mutex_lock(mutex);
 
 	codec->implementation->destroy(codec);
+
+	UNPROTECT_INTERFACE(codec->codec_interface);
+
 	memset(codec, 0, sizeof(*codec));
 	
 	if (mutex) switch_mutex_unlock(mutex);

Modified: freeswitch/trunk/src/switch_core_directory.c
==============================================================================
--- freeswitch/trunk/src/switch_core_directory.c	(original)
+++ freeswitch/trunk/src/switch_core_directory.c	Wed Nov 12 14:28:05 2008
@@ -49,6 +49,7 @@
 		dh->memory_pool = pool;
 	} else {
 		if ((status = switch_core_new_memory_pool(&dh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
+			UNPROTECT_INTERFACE(dh->directory_interface);
 			return status;
 		}
 		switch_set_flag(dh, SWITCH_DIRECTORY_FLAG_FREE_POOL);
@@ -77,6 +78,7 @@
 	switch_status_t status;
 
 	status = dh->directory_interface->directory_close(dh);
+	UNPROTECT_INTERFACE(dh->directory_interface);
 
 	if (switch_test_flag(dh, SWITCH_DIRECTORY_FLAG_FREE_POOL)) {
 		switch_core_destroy_memory_pool(&dh->memory_pool);

Modified: freeswitch/trunk/src/switch_core_file.c
==============================================================================
--- freeswitch/trunk/src/switch_core_file.c	(original)
+++ freeswitch/trunk/src/switch_core_file.c	Wed Nov 12 14:28:05 2008
@@ -76,6 +76,7 @@
 		fh->memory_pool = pool;
 	} else {
 		if ((status = switch_core_new_memory_pool(&fh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
+			UNPROTECT_INTERFACE(fh->file_interface);
 			return status;
 		}
 		switch_set_flag(fh, SWITCH_FILE_FLAG_FREE_POOL);
@@ -98,9 +99,11 @@
 	}
 
 	if ((status = fh->file_interface->file_open(fh, file_path)) != SWITCH_STATUS_SUCCESS) {
+		UNPROTECT_INTERFACE(fh->file_interface);
 		return status;
 	}
 
+
 	if ((flags & SWITCH_FILE_FLAG_READ)) {
 		fh->native_rate = fh->samplerate;
 	} else {
@@ -281,6 +284,8 @@
 
 	switch_resample_destroy(&fh->resampler);
 
+	UNPROTECT_INTERFACE(fh->file_interface);
+
 	if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
 		switch_core_destroy_memory_pool(&fh->memory_pool);
 	}

Modified: freeswitch/trunk/src/switch_core_session.c
==============================================================================
--- freeswitch/trunk/src/switch_core_session.c	(original)
+++ freeswitch/trunk/src/switch_core_session.c	Wed Nov 12 14:28:05 2008
@@ -87,11 +87,13 @@
 		if (val) {
 			const char *this_val;
 			session = (switch_core_session_t *) val;
-			switch_core_session_read_lock(session);
-			if ((this_val = switch_channel_get_variable(session->channel, var_name)) && (!strcmp(this_val, var_val))) {
-				switch_channel_hangup(switch_core_session_get_channel(session), cause);
+			if (switch_core_session_read_lock(session) == SWITCH_STATUS_SUCCESS) {
+				if (switch_channel_get_state(session->channel) < CS_HANGUP &&
+					(this_val = switch_channel_get_variable(session->channel, var_name)) && (!strcmp(this_val, var_val))) {
+					switch_channel_hangup(session->channel, cause);
+				}
+				switch_core_session_rwunlock(session);
 			}
-			switch_core_session_rwunlock(session);
 		}
 	}
 	switch_mutex_unlock(runtime.throttle_mutex);
@@ -826,8 +828,7 @@
 	*session = NULL;
 	switch_core_destroy_memory_pool(&pool);
 
-	switch_thread_rwlock_unlock(endpoint_interface->rwlock);
-	switch_thread_rwlock_unlock(endpoint_interface->parent->rwlock);
+	UNPROTECT_INTERFACE(endpoint_interface);
 }
 
 SWITCH_STANDARD_SCHED_FUNC(sch_heartbeat_callback)
@@ -1006,6 +1007,7 @@
 	uint32_t count = 0;
 	int32_t sps = 0;
 
+
 	if (use_uuid && switch_core_hash_find(session_manager.session_table, use_uuid)) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Duplicate UUID!\n");
         return NULL;
@@ -1016,6 +1018,8 @@
 		return NULL;
 	}
 
+	PROTECT_INTERFACE(endpoint_interface);
+
 	switch_mutex_lock(runtime.throttle_mutex);
 	count = session_manager.session_count;
 	sps = --runtime.sps;
@@ -1023,17 +1027,16 @@
 
 	if (sps <= 0) {
 		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error!\n");
+		UNPROTECT_INTERFACE(endpoint_interface);
 		return NULL;
 	}
 
 	if ((count + 1) > session_manager.session_limit) {
 		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n");
+		UNPROTECT_INTERFACE(endpoint_interface);
 		return NULL;
 	}
 
-	switch_thread_rwlock_rdlock(endpoint_interface->parent->rwlock);
-	switch_thread_rwlock_rdlock(endpoint_interface->rwlock);
-
 	if (pool && *pool) {
 		usepool = *pool;
 		*pool = NULL;
@@ -1114,7 +1117,9 @@
 		return NULL;
 	}
 
+	UNPROTECT_INTERFACE(endpoint_interface);
 	return switch_core_session_request(endpoint_interface, pool);
+
 }
 
 #ifndef SWITCH_PREFIX_DIR
@@ -1195,6 +1200,7 @@
 	if (!application_interface->application_function) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Function for %s\n", app);
 		switch_channel_hangup(session->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+		UNPROTECT_INTERFACE(application_interface);
 		return SWITCH_STATUS_FALSE;
 	}
 
@@ -1236,6 +1242,8 @@
 		switch_safe_free(expanded);
 	}
 
+	UNPROTECT_INTERFACE(application_interface);
+	
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -1282,11 +1290,7 @@
 
 	switch_channel_set_variable(session->channel, SWITCH_CURRENT_APPLICATION_VARIABLE, application_interface->interface_name);
 
-	switch_thread_rwlock_rdlock(application_interface->parent->rwlock);
-	switch_thread_rwlock_rdlock(application_interface->rwlock);
 	application_interface->application_function(session, arg);
-	switch_thread_rwlock_unlock(application_interface->rwlock);
-	switch_thread_rwlock_unlock(application_interface->parent->rwlock);
 	
 	if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE) == SWITCH_STATUS_SUCCESS) {
 		switch_channel_event_set_data(session->channel, event);

Modified: freeswitch/trunk/src/switch_core_speech.c
==============================================================================
--- freeswitch/trunk/src/switch_core_speech.c	(original)
+++ freeswitch/trunk/src/switch_core_speech.c	Wed Nov 12 14:28:05 2008
@@ -66,6 +66,7 @@
 		sh->memory_pool = pool;
 	} else {
 		if ((status = switch_core_new_memory_pool(&sh->memory_pool)) != SWITCH_STATUS_SUCCESS) {
+			UNPROTECT_INTERFACE(sh->speech_interface);
 			return status;
 		}
 		switch_set_flag(sh, SWITCH_SPEECH_FLAG_FREE_POOL);
@@ -139,6 +140,8 @@
 {
 	switch_status_t status = sh->speech_interface->speech_close(sh, flags);
 
+	UNPROTECT_INTERFACE(sh->speech_interface);
+
 	if (switch_test_flag(sh, SWITCH_SPEECH_FLAG_FREE_POOL)) {
 		switch_core_destroy_memory_pool(&sh->memory_pool);
 	}

Modified: freeswitch/trunk/src/switch_core_state_machine.c
==============================================================================
--- freeswitch/trunk/src/switch_core_state_machine.c	(original)
+++ freeswitch/trunk/src/switch_core_state_machine.c	Wed Nov 12 14:28:05 2008
@@ -91,8 +91,11 @@
 					}
 					
 					count++;
-
-					if ((extension = dialplan_interface->hunt_function(session, dparg, NULL)) != 0) {
+					
+					extension = dialplan_interface->hunt_function(session, dparg, NULL);
+					UNPROTECT_INTERFACE(dialplan_interface);
+					
+					if (extension) {
 						switch_channel_set_caller_extension(session->channel, extension);
 						switch_channel_set_state(session->channel, CS_EXECUTE);
 						goto end;

Modified: freeswitch/trunk/src/switch_core_timer.c
==============================================================================
--- freeswitch/trunk/src/switch_core_timer.c	(original)
+++ freeswitch/trunk/src/switch_core_timer.c	Wed Nov 12 14:28:05 2008
@@ -55,6 +55,7 @@
 		timer->memory_pool = pool;
 	} else {
 		if ((status = switch_core_new_memory_pool(&timer->memory_pool)) != SWITCH_STATUS_SUCCESS) {
+			UNPROTECT_INTERFACE(timer->timer_interface);
 			return status;
 		}
 		switch_set_flag(timer, SWITCH_TIMER_FLAG_FREE_POOL);
@@ -120,6 +121,7 @@
 	}
 
 	timer->timer_interface->timer_destroy(timer);
+	UNPROTECT_INTERFACE(timer->timer_interface);
 
 	if (switch_test_flag(timer, SWITCH_TIMER_FLAG_FREE_POOL)) {
 		switch_core_destroy_memory_pool(&timer->memory_pool);

Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c	(original)
+++ freeswitch/trunk/src/switch_ivr.c	Wed Nov 12 14:28:05 2008
@@ -409,6 +409,7 @@
 
 					switch_channel_clear_flag(channel, CF_BROADCAST);
 				}
+				UNPROTECT_INTERFACE(application_interface);
 			}
 		}
 	} else if (cmd_hash == CMD_UNICAST) {

Modified: freeswitch/trunk/src/switch_ivr_menu.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_menu.c	(original)
+++ freeswitch/trunk/src/switch_ivr_menu.c	Wed Nov 12 14:28:05 2008
@@ -477,6 +477,7 @@
 
 								if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
 									switch_core_session_exec(session, application_interface, app_arg);
+									UNPROTECT_INTERFACE(application_interface);
 									status = SWITCH_STATUS_SUCCESS;
 								}
 							}

Modified: freeswitch/trunk/src/switch_ivr_originate.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_originate.c	(original)
+++ freeswitch/trunk/src/switch_ivr_originate.c	Wed Nov 12 14:28:05 2008
@@ -115,6 +115,7 @@
 		if ((application_interface = switch_loadable_module_get_application_interface(app_name)) == 0) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", app_name);
 			switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+			UNPROTECT_INTERFACE(application_interface);
 			goto wbreak;
 		}
 

Modified: freeswitch/trunk/src/switch_ivr_play_say.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_play_say.c	(original)
+++ freeswitch/trunk/src/switch_ivr_play_say.c	Wed Nov 12 14:28:05 2008
@@ -293,6 +293,7 @@
 
 						if ((app = switch_loadable_module_get_application_interface(cmd)) != NULL) {
 							status = switch_core_session_exec(session, app, cmd_args);
+							UNPROTECT_INTERFACE(app);
 						} else {
 							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application %s\n", cmd);
 						}

Modified: freeswitch/trunk/src/switch_loadable_module.c
==============================================================================
--- freeswitch/trunk/src/switch_loadable_module.c	(original)
+++ freeswitch/trunk/src/switch_loadable_module.c	Wed Nov 12 14:28:05 2008
@@ -455,6 +455,8 @@
 						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
 										  "Deleting Codec '%s' (%s) %dhz %dms\n",
 										  impl->iananame, ptr->interface_name, impl->actual_samples_per_second, impl->microseconds_per_packet / 1000);
+						switch_core_session_hupall_matching_var("read_codec", impl->iananame, SWITCH_CAUSE_SYSTEM_SHUTDOWN);
+						switch_core_session_hupall_matching_var("write_codec", impl->iananame, SWITCH_CAUSE_SYSTEM_SHUTDOWN);
 						if (switch_core_hash_find(loadable_modules.codec_hash, impl->iananame)) {
 							switch_core_hash_delete(loadable_modules.codec_hash, impl->iananame);
 						}
@@ -560,6 +562,15 @@
 		for (ptr = old_module->module_interface->file_interface; ptr; ptr = ptr->next) {
 			if (ptr->interface_name) {
 				int i;
+
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Write lock interface '%s' to wait for existing references.\n", ptr->interface_name);
+				
+				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");
+				}
+
 				for (i = 0; ptr->extens[i]; i++) {
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleting File Format '%s'\n", ptr->extens[i]);
 					if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
@@ -577,7 +588,17 @@
 		const switch_speech_interface_t *ptr;
 
 		for (ptr = old_module->module_interface->speech_interface; ptr; ptr = ptr->next) {
+
 			if (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);
+				
+				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 Speech interface '%s'\n", ptr->interface_name);
 				if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
 					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "speech");
@@ -594,6 +615,15 @@
 
 		for (ptr = old_module->module_interface->asr_interface; ptr; ptr = ptr->next) {
 			if (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);
+				
+				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 Asr interface '%s'\n", ptr->interface_name);
 				if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
 					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "asr");
@@ -610,6 +640,15 @@
 
 		for (ptr = old_module->module_interface->directory_interface; ptr; ptr = ptr->next) {
 			if (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);
+				
+				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 Directory interface '%s'\n", ptr->interface_name);
 				if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
 					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "directory");
@@ -627,6 +666,14 @@
 
 		for (ptr = old_module->module_interface->chat_interface; ptr; ptr = ptr->next) {
 			if (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);
+				
+				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 Chat interface '%s'\n", ptr->interface_name);
 				if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
 					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "chat");
@@ -643,6 +690,13 @@
 
 		for (ptr = old_module->module_interface->say_interface; ptr; ptr = ptr->next) {
 			if (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);
+				
+				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 Say interface '%s'\n", ptr->interface_name);
 				if (switch_event_create(&event, SWITCH_EVENT_MODULE_UNLOAD) == SWITCH_STATUS_SUCCESS) {
 					switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "type", "say");
@@ -913,6 +967,7 @@
 	switch_mutex_unlock(loadable_modules.mutex);
 
 	if (force) {
+		switch_yield(1000000);
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PHEW!\n");
 	}
 
@@ -1239,8 +1294,12 @@
 
 	switch_mutex_lock(loadable_modules.mutex);
 	ptr = switch_core_hash_find(loadable_modules.endpoint_hash, name);
+	if (ptr) {
+		PROTECT_INTERFACE(ptr);
+	}
 	switch_mutex_unlock(loadable_modules.mutex);
 
+
 	return ptr;
 }
 
@@ -1263,57 +1322,41 @@
 		}
 	}
 	switch_mutex_unlock(loadable_modules.mutex);
-	return codec;
-}
 
-SWITCH_DECLARE(switch_dialplan_interface_t *) switch_loadable_module_get_dialplan_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.dialplan_hash, name, loadable_modules.mutex);
-}
-
-SWITCH_DECLARE(switch_timer_interface_t *) switch_loadable_module_get_timer_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.timer_hash, name, loadable_modules.mutex);
-}
-
-SWITCH_DECLARE(switch_application_interface_t *) switch_loadable_module_get_application_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.application_hash, name, loadable_modules.mutex);
-}
-
-SWITCH_DECLARE(switch_api_interface_t *) switch_loadable_module_get_api_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.api_hash, name, loadable_modules.mutex);
-}
-
-SWITCH_DECLARE(switch_file_interface_t *) switch_loadable_module_get_file_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.file_hash, name, loadable_modules.mutex);
-}
+	if (codec) {
+		PROTECT_INTERFACE(codec);
+	}
 
-SWITCH_DECLARE(switch_speech_interface_t *) switch_loadable_module_get_speech_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.speech_hash, name, loadable_modules.mutex);
+	return codec;
 }
 
-SWITCH_DECLARE(switch_asr_interface_t *) switch_loadable_module_get_asr_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.asr_hash, name, loadable_modules.mutex);
-}
+#define HASH_FUNC(_kind_) SWITCH_DECLARE(switch_##_kind_##_interface_t *) switch_loadable_module_get_##_kind_##_interface(const char *name)	\
+	{																	\
+		switch_##_kind_##_interface_t *i;								\
+		if ((i = switch_core_hash_find_locked(loadable_modules._kind_##_hash, name, loadable_modules.mutex))) {	\
+			PROTECT_INTERFACE(i);										\
+		}																\
+		return i;														\
+	}																	
+	
+HASH_FUNC(dialplan)
+HASH_FUNC(timer)
+HASH_FUNC(application)
+HASH_FUNC(api)
+HASH_FUNC(file)
+HASH_FUNC(speech)
+HASH_FUNC(asr)
+HASH_FUNC(directory)
 
-SWITCH_DECLARE(switch_directory_interface_t *) switch_loadable_module_get_directory_interface(const char *name)
-{
-	return switch_core_hash_find_locked(loadable_modules.directory_hash, name, loadable_modules.mutex);
-}
 
 SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interface(const char *name)
 {
-	return switch_core_hash_find_locked(loadable_modules.chat_hash, name, loadable_modules.mutex);
+    return switch_core_hash_find_locked(loadable_modules.chat_hash, name, loadable_modules.mutex);
 }
 
 SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(const char *name)
 {
-	return switch_core_hash_find_locked(loadable_modules.say_hash, name, loadable_modules.mutex);
+    return switch_core_hash_find_locked(loadable_modules.say_hash, name, loadable_modules.mutex);
 }
 
 SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(const char *relative_oid)
@@ -1472,13 +1515,10 @@
 
 
 	if (cmd && (api = switch_loadable_module_get_api_interface(cmd)) != 0) {
-		switch_thread_rwlock_rdlock(api->parent->rwlock);
-		switch_thread_rwlock_rdlock(api->rwlock);
 		if ((status = api->function(arg, session, stream)) != SWITCH_STATUS_SUCCESS) {
 			stream->write_function(stream, "COMMAND RETURNED ERROR!\n");
 		}
-		switch_thread_rwlock_unlock(api->rwlock);
-		switch_thread_rwlock_unlock(api->parent->rwlock);
+		UNPROTECT_INTERFACE(api);
 	} else {
 		status = SWITCH_STATUS_FALSE;
 		stream->write_function(stream, "INVALID COMMAND!\n");



More information about the Freeswitch-svn mailing list