]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add priority queue for events so important broadcasts like hold music can take preced...
authorAnthony Minessale <anthony.minessale@gmail.com>
Thu, 10 Dec 2009 01:29:02 +0000 (01:29 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Thu, 10 Dec 2009 01:29:02 +0000 (01:29 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15865 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/private/switch_core_pvt.h
src/include/switch_core.h
src/include/switch_types.h
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/event_handlers/mod_event_socket/mod_event_socket.c
src/switch_core_session.c
src/switch_ivr.c
src/switch_ivr_async.c
src/switch_ivr_bridge.c

index 2d7ac406eefd7a9e33d232b6d097123244fdd582..d0e28cacec10c3df763ee49cebd2338c5dd7e114 100644 (file)
@@ -134,6 +134,7 @@ struct switch_core_session {
        switch_queue_t *event_queue;
        switch_queue_t *message_queue;
        switch_queue_t *private_event_queue;
+       switch_queue_t *private_event_queue_pri;
        switch_thread_rwlock_t *bug_rwlock;
        switch_media_bug_t *bugs;
        switch_app_log_t *app_log;
index 3f9eddb584cb78deaee4ba2eb7b005d8426cc176..d96a9dbabb620642f67bdd8221b36274a3fa5286 100644 (file)
@@ -986,9 +986,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_event(_In_ switch_co
   \brief Queue a private event on a given session
   \param session the session to queue the message on
   \param event the event to queue
+  \param priority event has high priority
   \return the status returned by the message handler
 */
-SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event);
+SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event, switch_bool_t priority);
 
 
 /*! 
index 4a59925ec48473379549f62d9af8cdb8007c2cf3..c94b1eddb7d1c1cb1a5f21078acbb0038217fe21 100644 (file)
@@ -326,7 +326,8 @@ typedef enum {
        SMF_LOOP = (1 << 4),
        SMF_HOLD_BLEG = (1 << 5),
        SMF_IMMEDIATE = (1 << 6),
-       SMF_EXEC_INLINE = (1 << 7)
+       SMF_EXEC_INLINE = (1 << 7),
+       SMF_PRIORITY = (1 << 8)
 } switch_media_flag_enum_t;
 typedef uint32_t switch_media_flag_t;
 
@@ -919,6 +920,7 @@ typedef enum {
        CF_UNICAST,
        CF_VIDEO,
        CF_EVENT_LOCK,
+       CF_EVENT_LOCK_PRI,
        CF_RESET,
        CF_ORIGINATING,
        CF_STOP_BROADCAST,
index ab9e2445010c4dfd2a7c59468970658358b8b2d1..db07c3f8e9029fd5aea55360e7146b370e9e3853 100644 (file)
@@ -2938,7 +2938,8 @@ void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly)
                                        switch_channel_set_flag(tech_pvt->channel, CF_HOLD);
                                        switch_ivr_hold_uuid(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), NULL, 0);
                                } else {
-                                       switch_ivr_broadcast(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), stream, SMF_ECHO_ALEG | SMF_LOOP);
+                                       switch_ivr_broadcast(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), stream, 
+                                                                                SMF_ECHO_ALEG | SMF_LOOP | SMF_PRIORITY);
                                        switch_yield(250000);
                                }
                        }
index d818d1b6ca3ecfd7a6a2dddd26f7450ed9902ff8..7f24d2b9e58a1c105822d46bf6b341aa427c9926 100644 (file)
@@ -1655,7 +1655,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
 
                if (zstr(uuid) && listener->session) {
                        if (async) {
-                               if ((status = switch_core_session_queue_private_event(listener->session, event)) == SWITCH_STATUS_SUCCESS) {
+                               if ((status = switch_core_session_queue_private_event(listener->session, event, SWITCH_FALSE)) == SWITCH_STATUS_SUCCESS) {
                                        switch_snprintf(reply, reply_len, "+OK");
                                } else {
                                        switch_snprintf(reply, reply_len, "-ERR memory error");
@@ -1666,7 +1666,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
                        }
                } else {
                        if (!zstr(uuid) && (session = switch_core_session_locate(uuid))) {
-                               if ((status = switch_core_session_queue_private_event(session, event)) == SWITCH_STATUS_SUCCESS) {
+                               if ((status = switch_core_session_queue_private_event(session, event, SWITCH_FALSE)) == SWITCH_STATUS_SUCCESS) {
                                        switch_snprintf(reply, reply_len, "+OK");
                                } else {
                                        switch_snprintf(reply, reply_len, "-ERR memory error");
index cfdb420adb4ee4f92da3049925ac91aa35a82052..2e900c8e9f2cd07e82913a80451a7ed7ec3318e3 100644 (file)
@@ -847,15 +847,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_event(switch_core_se
        return status;
 }
 
-SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(switch_core_session_t *session, switch_event_t **event)
+SWITCH_DECLARE(switch_status_t) switch_core_session_queue_private_event(switch_core_session_t *session, switch_event_t **event, switch_bool_t priority)
 {
        switch_status_t status = SWITCH_STATUS_FALSE;
+       switch_queue_t *queue;
 
        switch_assert(session != NULL);
 
        if (session->private_event_queue) {
+               queue = priority ? session->private_event_queue_pri : session->private_event_queue;
+               
                (*event)->event_id = SWITCH_EVENT_PRIVATE_COMMAND;
-               if (switch_queue_trypush(session->private_event_queue, *event) == SWITCH_STATUS_SUCCESS) {
+               if (switch_queue_trypush(queue, *event) == SWITCH_STATUS_SUCCESS) {
                        *event = NULL;
                        switch_core_session_kill_channel(session, SWITCH_SIG_BREAK);
                        status = SWITCH_STATUS_SUCCESS;
@@ -878,8 +881,16 @@ SWITCH_DECLARE(uint32_t) switch_core_session_private_event_count(switch_core_ses
        switch_channel_t *channel = switch_core_session_get_channel(session);
        uint32_t count = 0;
        
-       if (!switch_channel_test_flag(channel, CF_EVENT_LOCK) && session->private_event_queue) {
-               count = switch_queue_size(session->private_event_queue);
+       if (session->private_event_queue) {
+
+               if (!switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
+                       count = switch_queue_size(session->private_event_queue);
+               }
+
+               if (!switch_channel_test_flag(channel, CF_EVENT_LOCK_PRI)) {
+                       count += switch_queue_size(session->private_event_queue_pri);
+               }
+
                if (count == 0) {
                        check_media(session);
                }
@@ -893,13 +904,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_private_event(switch
        switch_status_t status = SWITCH_STATUS_FALSE;
        void *pop;
        switch_channel_t *channel = switch_core_session_get_channel(session);
+       switch_queue_t *queue;
+       
+       if (session->private_event_queue) {
+               if (switch_queue_size(session->private_event_queue_pri)) {
+                       queue = session->private_event_queue_pri;
 
-       if (switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
-               return status;
-       }
+                       if (switch_channel_test_flag(channel, CF_EVENT_LOCK_PRI)) {
+                               return SWITCH_STATUS_FALSE;
+                       }
+               } else {
+                       queue = session->private_event_queue;
+                       
+                       if (switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
+                               return SWITCH_STATUS_FALSE;
+                       }
+               }
 
-       if (session->private_event_queue) {
-               if ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
+               if ((status = (switch_status_t) switch_queue_trypop(queue, &pop)) == SWITCH_STATUS_SUCCESS) {
                        *event = (switch_event_t *) pop;
                } else {
                        check_media(session);
@@ -916,6 +938,9 @@ SWITCH_DECLARE(uint32_t) switch_core_session_flush_private_events(switch_core_se
        void *pop;
 
        if (session->private_event_queue) {
+               while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue_pri, &pop)) == SWITCH_STATUS_SUCCESS) {
+                       x++;
+               }
                while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
                        x++;
                }
@@ -1327,6 +1352,7 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
        switch_queue_create(&session->message_queue, SWITCH_MESSAGE_QUEUE_LEN, session->pool);
        switch_queue_create(&session->event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
        switch_queue_create(&session->private_event_queue, SWITCH_EVENT_QUEUE_LEN, session->pool);
+       switch_queue_create(&session->private_event_queue_pri, SWITCH_EVENT_QUEUE_LEN, session->pool);
 
        switch_mutex_lock(runtime.session_hash_mutex);
        switch_core_hash_insert(session_manager.session_table, session->uuid_str, session);
index 6236ee12cfd73e698b241d2b0d483f036e3b6842..a6d54a4dfb0d745b5242411057b70cdaf87f612e 100644 (file)
@@ -461,6 +461,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
        unsigned long CMD_UNICAST = switch_hashfunc_default("unicast", &hlen);
        char *lead_frames = switch_event_get_header(event, "lead-frames");
        char *event_lock = switch_event_get_header(event, "event-lock");
+       char *event_lock_pri = switch_event_get_header(event, "event-lock-pri");
        switch_status_t status = SWITCH_STATUS_FALSE;
 
        if (zstr(cmd)) {
@@ -476,6 +477,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
                switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK);
        }
 
+       if (switch_true(event_lock_pri)) {
+               switch_channel_set_flag_recursive(channel, CF_EVENT_LOCK_PRI);
+       }
+
        if (lead_frames) {
                switch_frame_t *read_frame;
                int frame_count = atoi(lead_frames);
@@ -606,6 +611,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *se
   done:
        switch_channel_clear_flag_recursive(channel, CF_EVENT_PARSE);
        switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK);
+       switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK_PRI);
 
        return status;
 }
index b9d953c5fc5b56a8c6dc21dea30f5806daf8c950..73a02768b901b32c2d73620bcab18299905192d7 100644 (file)
@@ -1740,7 +1740,7 @@ static switch_bool_t tone_detect_callback(switch_media_bug_t *bug, void *user_da
                                                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", cont->list[i].app);
                                                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", cont->list[i].data);
                                                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
-                                                               switch_core_session_queue_private_event(cont->session, &event);
+                                                               switch_core_session_queue_private_event(cont->session, &event, SWITCH_FALSE);
                                                        }
                                                }
 
@@ -2713,8 +2713,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true");
+
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
-                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-lock", "true");
+                               
                                if ((flags & SMF_LOOP)) {
                                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1);
                                }
@@ -2723,7 +2725,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true");
                                }
                                
-                               switch_core_session_queue_private_event(other_session, &event);
+                               switch_core_session_queue_private_event(other_session, &event, (flags & SMF_PRIORITY));
                        }
                }
                
@@ -2745,15 +2747,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
                                switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true");
                                switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
-                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-lock", "true");
+                               
                                if ((flags & SMF_LOOP)) {
                                        switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1);
                                }
                                if ((flags & SMF_HOLD_BLEG)) {
                                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true");
                                }
-                               switch_core_session_queue_private_event(session, &event);
+
+                               switch_core_session_queue_private_event(session, &event, (flags & SMF_PRIORITY));
+
                                if (nomedia) switch_channel_set_flag(channel, CF_BROADCAST_DROP_MEDIA);
                        }
                }
@@ -2765,8 +2770,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_broadcast(const char *uuid, const cha
                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", "hangup");
                        switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", cause);
-                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-lock", "true");
-                       switch_core_session_queue_private_event(session, &event);
+                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true");
+                       switch_core_session_queue_private_event(session, &event, (flags & SMF_PRIORITY));
                }
        }
 
index 437c6340e2121c3390c370067d13009288114464..c5ba9278ea6bbf4d2e06d8b7a970fec72bdfe137 100644 (file)
@@ -1059,7 +1059,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
                                        switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", data);
                                        switch_event_add_header(execute_event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
                                        switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true");
-                                       switch_core_session_queue_private_event(session, &execute_event);
+                                       switch_core_session_queue_private_event(session, &execute_event, SWITCH_FALSE);
                                        a_leg->skip_frames = DEFAULT_LEAD_FRAMES;
                                }
 
@@ -1074,7 +1074,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
                                        switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "execute-app-arg", data);
                                        switch_event_add_header(execute_event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
                                        switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true");
-                                       switch_core_session_queue_private_event(peer_session, &execute_event);
+                                       switch_core_session_queue_private_event(peer_session, &execute_event, SWITCH_FALSE);
                                        b_leg->skip_frames = DEFAULT_LEAD_FRAMES;
                                }
                        }