]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
If a queue uses dynamic realtime members, then the member list should be updated...
authorMark Michelson <mmichelson@digium.com>
Wed, 1 Aug 2007 13:59:59 +0000 (13:59 +0000)
committerMark Michelson <mmichelson@digium.com>
Wed, 1 Aug 2007 13:59:59 +0000 (13:59 +0000)
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: https://origsvn.digium.com/svn/asterisk/branches/1.4@77852 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_queue.c

index aafc0e17c5c3f4dbb2bb374f76088765682d2307..e257493750854b85500b872911e932fe2064b575 100644 (file)
@@ -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)