]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
look out below....(make current)
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 12 Nov 2008 19:28:05 +0000 (19:28 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 12 Nov 2008 19:28:05 +0000 (19:28 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@10363 d0543943-73ff-0310-b7d9-9358b9ac24b2

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

index 989672562930ac4f91f4e3cd4a1b7df2ed06e123..9a0fc6fd1885a5670cb9d88ecc9dcccd50b3905a 100644 (file)
@@ -392,6 +392,11 @@ SWITCH_DECLARE(uint32_t) switch_core_codec_next_id(void);
        }
 
 
+#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:
index 3f252278289ef432557e18e058ea55e2263dc0e0..84d9aa4c873324204391d1c0327feb3fed079537 100644 (file)
@@ -39,12 +39,14 @@ SWITCH_MODULE_DEFINITION(mod_dialplan_asterisk, mod_dialplan_asterisk_load, NULL
 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)
index 0d34fe1d9ffbdbf3754484d42cc4f2f02eed055a..651568084925120db99fc6a0c784b8008ba04177 100644 (file)
@@ -1168,9 +1168,9 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile)
                                                } 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 @@ switch_status_t config_sofia(int reload, char *profile_name)
                                                } 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)) {
index 112aea997f482e2600e1c63db0fd8af26ff554dc..2fe6be6eb66973112fa5577b66fa3caebba28347 100644 (file)
@@ -2865,10 +2865,15 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
 
                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 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
 #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);
index 8e89d28c20db601377f17eba7de0dd47ee651f58..346f9b9597f70e008e8890bd1d1ef53373841187 100644 (file)
@@ -249,6 +249,11 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
        }
 
  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);
index 88157fcdf6479d729905c84ab0e132c2f7c00d1e..edf050c8efc2b04fa786dcf9a6398e815f562949 100644 (file)
@@ -2222,6 +2222,7 @@ static JSBool session_execute(JSContext * cx, JSObject * obj, uintN argc, jsval
                                check_hangup_hook(jss, &ret);
                                retval = JS_TRUE;
                        }
+                       UNPROTECT_INTERFACE(application_interface);
                }
        }
 
index fbe13d0801a45aa426ce96e8ef34f83a91630455..cd7833a904ed0d94e136106877a02ceb5959d2d4 100644 (file)
@@ -64,6 +64,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_asr_open(switch_asr_handle_t *ah,
                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_DECLARE(switch_status_t) switch_core_asr_close(switch_asr_handle_t *ah, s
        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);
index b87a6503f5f52062321d494352249a6fa94c533a..637d85517030115ed1d6ff1afdd35fce2755d5ad 100644 (file)
@@ -451,12 +451,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_init(switch_codec_t *codec, co
 
                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 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_destroy(switch_codec_t *codec)
        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);
index 3eedf4b2313ef75e435fc851253e228a0c9b4d98..6a719d37f92c2b384c5e19ab3cca440793fa5ea2 100644 (file)
@@ -49,6 +49,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_directory_open(switch_directory_hand
                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_DECLARE(switch_status_t) switch_core_directory_close(switch_directory_han
        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);
index 5614ffebae3671db2f1f7028be5d55fa56971af7..b3b3677b9d759afe1bf984d0b7e5ef2dd34ef279 100644 (file)
@@ -76,6 +76,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
                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 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
        }
 
        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_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
 
        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);
        }
index debcb4a487e55a13f720229654f2c4ed7465e85d..da22ddde8a6237c4863efc0d2bfb130f18283356 100644 (file)
@@ -87,11 +87,13 @@ SWITCH_DECLARE(void) switch_core_session_hupall_matching_var(const char *var_nam
                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 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t *
        *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 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(const s
        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 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(const s
                return NULL;
        }
 
+       PROTECT_INTERFACE(endpoint_interface);
+
        switch_mutex_lock(runtime.throttle_mutex);
        count = session_manager.session_count;
        sps = --runtime.sps;
@@ -1023,17 +1027,16 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(const s
 
        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 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_by_name(cons
                return NULL;
        }
 
+       UNPROTECT_INTERFACE(endpoint_interface);
        return switch_core_session_request(endpoint_interface, pool);
+
 }
 
 #ifndef SWITCH_PREFIX_DIR
@@ -1195,6 +1200,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application(switch_c
        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_DECLARE(switch_status_t) switch_core_session_execute_application(switch_c
                switch_safe_free(expanded);
        }
 
+       UNPROTECT_INTERFACE(application_interface);
+       
        return SWITCH_STATUS_SUCCESS;
 }
 
@@ -1282,11 +1290,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t *
 
        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);
index 9cab0865f5a2eea44bc1e948f36c6915960b0de1..8b2184abdb913ae711dcde85d21245d89cdb2196 100644 (file)
@@ -66,6 +66,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_speech_open(switch_speech_handle_t *
                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_DECLARE(switch_status_t) switch_core_speech_close(switch_speech_handle_t
 {
        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);
        }
index 0bf7bd9cc5f3d06d3c96d13fd4f80c734e66c5b6..dff6ef2d1bab8c694b9597705a582d37a3629669 100644 (file)
@@ -91,8 +91,11 @@ static void switch_core_standard_on_routing(switch_core_session_t *session)
                                        }
                                        
                                        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;
index d9502bb8f2cde575a2a033debebdbf96d0e5f515..0206028fb912a9f8af026baf0f65c18f7e6585c7 100644 (file)
@@ -55,6 +55,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, co
                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 @@ SWITCH_DECLARE(switch_status_t) switch_core_timer_destroy(switch_timer_t *timer)
        }
 
        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);
index b41ab18d4ee4c9021c3a6831bd9415f6e1acb590..c52c50daf2ca9233bdb0c2cb2af835d990eb6a76 100644 (file)
@@ -409,6 +409,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
 
                                        switch_channel_clear_flag(channel, CF_BROADCAST);
                                }
+                               UNPROTECT_INTERFACE(application_interface);
                        }
                }
        } else if (cmd_hash == CMD_UNICAST) {
index 38b1e857c6c0e14f21a5756703ac419d4f703e11..f72257f641e19075424520f1f5c11bafbfc9c125 100644 (file)
@@ -477,6 +477,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_menu_execute(switch_core_session_t *s
 
                                                                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;
                                                                }
                                                        }
index 88cc6d564e0a92dd9c500f603512f585ed6b8c19..328c9eed4913db2b104ebae362105dad798137fd 100644 (file)
@@ -115,6 +115,7 @@ static void *SWITCH_THREAD_FUNC collect_thread_run(switch_thread_t *thread, void
                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;
                }
 
index 06004f2e48017abed32dfdc4f7b78cc1438d8e7d..e20d49b5d2dc8ca15fc50868724c4c2ea2891f8a 100644 (file)
@@ -293,6 +293,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *s
 
                                                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);
                                                }
index ad448ad5724c2c910e7f5f1fe50ff2158a72d4a0..1dcb84dacb803fcce550a823cca813a37657c0fe 100644 (file)
@@ -455,6 +455,8 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
                                                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 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
                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 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
                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 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
 
                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 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
 
                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 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
 
                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 @@ static switch_status_t switch_loadable_module_unprocess(switch_loadable_module_t
 
                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_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir,
        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_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoin
 
        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_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_inte
                }
        }
        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 @@ SWITCH_DECLARE(switch_status_t) switch_api_execute(const char *cmd, const char *
 
 
        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");