]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
prevent race while changing codecs mid call
authorAnthony Minessale <anthm@freeswitch.org>
Sat, 4 Dec 2010 02:22:02 +0000 (20:22 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Sat, 4 Dec 2010 02:22:14 +0000 (20:22 -0600)
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_core_io.c

index 451d7881b7be17196f7c205125d56b6c4019ff34..6416778ab0d9047249c5331b8a1fb74f8e70c477 100644 (file)
@@ -2673,6 +2673,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
                        switch_core_session_lock_codec_write(tech_pvt->session);
                        switch_core_session_lock_codec_read(tech_pvt->session);
                        resetting = 1;
+                       switch_yield(tech_pvt->read_impl.microseconds_per_packet);
                        switch_core_codec_destroy(&tech_pvt->read_codec);
                        switch_core_codec_destroy(&tech_pvt->write_codec);
                } else {
index cd25622b5d27741f85ff55f1d524d8d25b2a51f6..6f3e65a9f490f38a75cf9a7f3141888b8a9c71dc 100644 (file)
@@ -110,6 +110,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
 
        switch_assert(session != NULL);
 
+
+       if (switch_mutex_trylock(session->codec_read_mutex) == SWITCH_STATUS_SUCCESS) {
+               switch_mutex_unlock(session->codec_read_mutex);
+       } else {
+               switch_cond_next();
+               *frame = &runtime.dummy_cng_frame;
+               return SWITCH_STATUS_SUCCESS;
+       }
+
        if (!(session->read_codec && session->read_codec->implementation && switch_core_codec_ready(session->read_codec))) {
                if (switch_channel_test_flag(session->channel, CF_PROXY_MODE) || switch_channel_get_state(session->channel) == CS_HIBERNATE) {
                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s reading on a session with no media!\n",
@@ -641,11 +650,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
                return SWITCH_STATUS_FALSE;
        }
 
+       if (switch_mutex_trylock(session->codec_write_mutex) == SWITCH_STATUS_SUCCESS) {
+               switch_mutex_unlock(session->codec_write_mutex);
+       } else {
+               return SWITCH_STATUS_SUCCESS;
+       }
+
        if (switch_test_flag(frame, SFF_CNG)) {
                if (switch_channel_test_flag(session->channel, CF_ACCEPT_CNG)) {
                        pass_cng = 1;
+               } else {
+                       return SWITCH_STATUS_SUCCESS;
                }
-               return SWITCH_STATUS_SUCCESS;
        }
 
        if (!(session->write_codec && switch_core_codec_ready(session->write_codec)) && !pass_cng) {