From 751e0291ee9bb99119fec0c1cb5814919ec5d8f7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 22 Dec 2010 19:10:30 -0600 Subject: [PATCH] prevent race on execute_on_answer called from the B-leg of a call --- src/include/switch_types.h | 1 + src/switch_core_session.c | 20 +++++++++++++++++--- src/switch_ivr.c | 15 +++++++++++++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index e04f437eb3..76af5a40ed 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1096,6 +1096,7 @@ typedef enum { CF_RECOVERED, CF_JITTERBUFFER, CF_DIALPLAN, + CF_BLOCK_BROADCAST_UNTIL_MEDIA, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ CF_FLAG_MAX } switch_channel_flag_t; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index c2766170a8..252b5e205b 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -1841,6 +1841,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_async(sw switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", arg); } + if (!switch_channel_test_flag(session->channel, CF_PROXY_MODE)) { + switch_channel_set_flag(session->channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); + } + switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE); @@ -1891,9 +1895,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag switch_goto_status(SWITCH_STATUS_FALSE, done); } } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, - "Cannot execute app '%s' media required on an outbound channel that does not have media established\n", app); - switch_goto_status(SWITCH_STATUS_FALSE, done); + uint32_t ready = 0, sanity = 2000; + + do { + sanity--; + ready = switch_channel_media_ready(session->channel); + switch_cond_next(); + } while(!ready && sanity); + + if (!ready) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "Cannot execute app '%s' media required on an outbound channel that does not have media established\n", app); + switch_goto_status(SWITCH_STATUS_FALSE, done); + } } } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 68d5a55b40..82c6ff4791 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -698,12 +698,23 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_messages(switch_core_sessio SWITCH_DECLARE(switch_status_t) switch_ivr_parse_all_events(switch_core_session_t *session) { int x = 0; - + switch_channel_t *channel; switch_ivr_parse_all_messages(session); - while (switch_ivr_parse_next_event(session) == SWITCH_STATUS_SUCCESS) + channel = switch_core_session_get_channel(session); + + if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA)) { + if (switch_channel_media_ready(channel)) { + switch_channel_clear_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); + } else { + return SWITCH_STATUS_SUCCESS; + } + } + + while (switch_ivr_parse_next_event(session) == SWITCH_STATUS_SUCCESS) { x++; + } if (x) { switch_ivr_sleep(session, 0, SWITCH_TRUE, NULL);