From 7aa72b67df8beec7996e3f7532a234cb61e6e26b Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 3 Dec 2010 20:22:02 -0600 Subject: [PATCH] prevent race while changing codecs mid call --- src/mod/endpoints/mod_sofia/sofia_glue.c | 1 + src/switch_core_io.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 451d7881b7..6416778ab0 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -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 { diff --git a/src/switch_core_io.c b/src/switch_core_io.c index cd25622b5d..6f3e65a9f4 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -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) {