aboutsummaryrefslogtreecommitdiffstats
path: root/apps/app_queue.c
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2007-08-01 13:59:59 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2007-08-01 13:59:59 +0000
commitd8e14b731d6bc7198529b487477b35c2b4a1acb0 (patch)
tree0f99f9204a643390748062944a316257bd9840d0 /apps/app_queue.c
parent6e7549ec123008e4fceffa25987850050deee5b3 (diff)
If a queue uses dynamic realtime members, then the member list should be updated after each attempt to call the queue.
This fixes an issue where if a caller calls into a queue where no one is logged in, they would wait forever even if a member logged in at some point. (closes issue #10346, reported by and tested by blitzrage, patched by me) git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@77852 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r--apps/app_queue.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index aafc0e17c..e25749375 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -1167,6 +1167,57 @@ static struct call_queue *load_realtime_queue(const char *queuename)
return q;
}
+static void update_realtime_members(struct call_queue *q)
+{
+ struct ast_config *member_config = NULL;
+ struct member *m, *prev_m, *next_m;
+ char *interface = NULL;
+
+ member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL);
+ if (!member_config) {
+ /*This queue doesn't have realtime members*/
+ if (option_debug > 2)
+ ast_log(LOG_DEBUG, "Queue %s has no realtime members defined. No need for update\n", q->name);
+ return;
+ }
+
+ ast_mutex_lock(&q->lock);
+
+ /* Temporarily set non-dynamic members dead so we can detect deleted ones.*/
+ for (m = q->members; m; m = m->next) {
+ if (!m->dynamic)
+ m->dead = 1;
+ }
+
+ while ((interface = ast_category_browse(member_config, interface))) {
+ rt_handle_member_record(q, interface,
+ S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
+ ast_variable_retrieve(member_config, interface, "penalty"),
+ ast_variable_retrieve(member_config, interface, "paused"));
+ }
+
+ /* Delete all realtime members that have been deleted in DB. */
+ m = q->members;
+ prev_m = NULL;
+ while (m) {
+ next_m = m->next;
+ if (m->dead) {
+ if (prev_m) {
+ prev_m->next = next_m;
+ } else {
+ q->members = next_m;
+ }
+ remove_from_interfaces(m->interface);
+ q->membercount--;
+ free(m);
+ } else {
+ prev_m = m;
+ }
+ m = next_m;
+ }
+ ast_mutex_unlock(&q->lock);
+}
+
static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
{
struct call_queue *q;
@@ -3485,6 +3536,9 @@ check_turns:
break;
}
+ /* If using dynamic realtime members, we should regenerate the member list for this queue */
+ update_realtime_members(qe.parent);
+
/* OK, we didn't get anybody; wait for 'retry' seconds; may get a digit to exit with */
res = wait_a_bit(&qe);
if (res)