]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
prevent race on execute_on_answer called from the B-leg of a call
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 23 Dec 2010 01:10:30 +0000 (19:10 -0600)
committerBrian West <brian@freeswitch.org>
Thu, 23 Dec 2010 01:10:30 +0000 (19:10 -0600)
src/include/switch_types.h
src/switch_core_session.c
src/switch_ivr.c

index e04f437eb30bf52181ca222594b5f658297926d5..76af5a40edda25e70e8cc900a5197a81d8ee250d 100644 (file)
@@ -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;
index c2766170a81a21d4ca93548ab93d93f88e2267f4..252b5e205b004bf5f7a9a1cd16e05fea1dce778e 100644 (file)
@@ -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);
+                       }
                }
        }
 
index 68d5a55b403ff77f99178fdaa0f4afb060b48d0a..82c6ff4791822128a4106b9ba6b847c7e0dcb9c4 100644 (file)
@@ -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);