diff options
author | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-08-01 13:59:59 +0000 |
---|---|---|
committer | mmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-08-01 13:59:59 +0000 |
commit | d8e14b731d6bc7198529b487477b35c2b4a1acb0 (patch) | |
tree | 0f99f9204a643390748062944a316257bd9840d0 /apps/app_queue.c | |
parent | 6e7549ec123008e4fceffa25987850050deee5b3 (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.c | 54 |
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) |