add priority queue for events so important broadcasts like hold music can take precedenced over event-lock

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15865 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2009-12-10 01:29:02 +00:00
parent ca7d414eb8
commit 6fde2f3961
9 changed files with 66 additions and 24 deletions

View File

@ -134,6 +134,7 @@ struct switch_core_session {
switch_queue_t *event_queue; switch_queue_t *event_queue;
switch_queue_t *message_queue; switch_queue_t *message_queue;
switch_queue_t *private_event_queue; switch_queue_t *private_event_queue;
switch_queue_t *private_event_queue_pri;
switch_thread_rwlock_t *bug_rwlock; switch_thread_rwlock_t *bug_rwlock;
switch_media_bug_t *bugs; switch_media_bug_t *bugs;
switch_app_log_t *app_log; switch_app_log_t *app_log;

View 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 \brief Queue a private event on a given session
\param session the session to queue the message on \param session the session to queue the message on
\param event the event to queue \param event the event to queue
\param priority event has high priority
\return the status returned by the message handler \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);
/*! /*!

View File

@ -326,7 +326,8 @@ typedef enum {
SMF_LOOP = (1 << 4), SMF_LOOP = (1 << 4),
SMF_HOLD_BLEG = (1 << 5), SMF_HOLD_BLEG = (1 << 5),
SMF_IMMEDIATE = (1 << 6), SMF_IMMEDIATE = (1 << 6),
SMF_EXEC_INLINE = (1 << 7) SMF_EXEC_INLINE = (1 << 7),
SMF_PRIORITY = (1 << 8)
} switch_media_flag_enum_t; } switch_media_flag_enum_t;
typedef uint32_t switch_media_flag_t; typedef uint32_t switch_media_flag_t;
@ -919,6 +920,7 @@ typedef enum {
CF_UNICAST, CF_UNICAST,
CF_VIDEO, CF_VIDEO,
CF_EVENT_LOCK, CF_EVENT_LOCK,
CF_EVENT_LOCK_PRI,
CF_RESET, CF_RESET,
CF_ORIGINATING, CF_ORIGINATING,
CF_STOP_BROADCAST, CF_STOP_BROADCAST,

View 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_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); switch_ivr_hold_uuid(switch_channel_get_variable(tech_pvt->channel, SWITCH_SIGNAL_BOND_VARIABLE), NULL, 0);
} else { } 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); switch_yield(250000);
} }
} }

View File

@ -1655,7 +1655,7 @@ static switch_status_t parse_command(listener_t *listener, switch_event_t **even
if (zstr(uuid) && listener->session) { if (zstr(uuid) && listener->session) {
if (async) { 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"); switch_snprintf(reply, reply_len, "+OK");
} else { } else {
switch_snprintf(reply, reply_len, "-ERR memory error"); 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 { } else {
if (!zstr(uuid) && (session = switch_core_session_locate(uuid))) { 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"); switch_snprintf(reply, reply_len, "+OK");
} else { } else {
switch_snprintf(reply, reply_len, "-ERR memory error"); switch_snprintf(reply, reply_len, "-ERR memory error");

View File

@ -847,15 +847,18 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_event(switch_core_se
return status; 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_status_t status = SWITCH_STATUS_FALSE;
switch_queue_t *queue;
switch_assert(session != NULL); switch_assert(session != NULL);
if (session->private_event_queue) { if (session->private_event_queue) {
queue = priority ? session->private_event_queue_pri : session->private_event_queue;
(*event)->event_id = SWITCH_EVENT_PRIVATE_COMMAND; (*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; *event = NULL;
switch_core_session_kill_channel(session, SWITCH_SIG_BREAK); switch_core_session_kill_channel(session, SWITCH_SIG_BREAK);
status = SWITCH_STATUS_SUCCESS; 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); switch_channel_t *channel = switch_core_session_get_channel(session);
uint32_t count = 0; uint32_t count = 0;
if (!switch_channel_test_flag(channel, CF_EVENT_LOCK) && session->private_event_queue) { if (session->private_event_queue) {
count = switch_queue_size(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) { if (count == 0) {
check_media(session); 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; switch_status_t status = SWITCH_STATUS_FALSE;
void *pop; void *pop;
switch_channel_t *channel = switch_core_session_get_channel(session); switch_channel_t *channel = switch_core_session_get_channel(session);
switch_queue_t *queue;
if (switch_channel_test_flag(channel, CF_EVENT_LOCK)) {
return status;
}
if (session->private_event_queue) { if (session->private_event_queue) {
if ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) { if (switch_queue_size(session->private_event_queue_pri)) {
queue = session->private_event_queue_pri;
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 ((status = (switch_status_t) switch_queue_trypop(queue, &pop)) == SWITCH_STATUS_SUCCESS) {
*event = (switch_event_t *) pop; *event = (switch_event_t *) pop;
} else { } else {
check_media(session); check_media(session);
@ -916,6 +938,9 @@ SWITCH_DECLARE(uint32_t) switch_core_session_flush_private_events(switch_core_se
void *pop; void *pop;
if (session->private_event_queue) { 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) { while ((status = (switch_status_t) switch_queue_trypop(session->private_event_queue, &pop)) == SWITCH_STATUS_SUCCESS) {
x++; 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->message_queue, SWITCH_MESSAGE_QUEUE_LEN, session->pool);
switch_queue_create(&session->event_queue, SWITCH_EVENT_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, 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_mutex_lock(runtime.session_hash_mutex);
switch_core_hash_insert(session_manager.session_table, session->uuid_str, session); switch_core_hash_insert(session_manager.session_table, session->uuid_str, session);

View 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); unsigned long CMD_UNICAST = switch_hashfunc_default("unicast", &hlen);
char *lead_frames = switch_event_get_header(event, "lead-frames"); char *lead_frames = switch_event_get_header(event, "lead-frames");
char *event_lock = switch_event_get_header(event, "event-lock"); 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; switch_status_t status = SWITCH_STATUS_FALSE;
if (zstr(cmd)) { 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); 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) { if (lead_frames) {
switch_frame_t *read_frame; switch_frame_t *read_frame;
int frame_count = atoi(lead_frames); 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: done:
switch_channel_clear_flag_recursive(channel, CF_EVENT_PARSE); 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);
switch_channel_clear_flag_recursive(channel, CF_EVENT_LOCK_PRI);
return status; return status;
} }

View 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-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_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_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, "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-name", app);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path); 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(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-lock", "true");
if ((flags & SMF_LOOP)) { if ((flags & SMF_LOOP)) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1); 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_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, "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-name", app);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path); 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(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event-lock", "true");
if ((flags & SMF_LOOP)) { if ((flags & SMF_LOOP)) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1);
} }
if ((flags & SMF_HOLD_BLEG)) { if ((flags & SMF_HOLD_BLEG)) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true"); 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); 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, "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-name", "hangup");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", cause); 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_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); switch_core_session_queue_private_event(session, &event, (flags & SMF_PRIORITY));
} }
} }

View 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_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(execute_event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); 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; 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_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(execute_event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
switch_event_add_header_string(execute_event, SWITCH_STACK_BOTTOM, "event-lock", "true"); 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; b_leg->skip_frames = DEFAULT_LEAD_FRAMES;
} }
} }