summaryrefslogtreecommitdiff
path: root/apps/app_queue.c
diff options
context:
space:
mode:
authorTerry Wilson <twilson@digium.com>2011-10-25 20:07:59 +0000
committerTerry Wilson <twilson@digium.com>2011-10-25 20:07:59 +0000
commitf8351a83427f7fdbc0e8b0f4b5c6f16425c2fcee (patch)
tree1fae57bc8652652d087de38c757c192c3b397e73 /apps/app_queue.c
parent5749ef5be87eaaa38208a31f8e486d4ae9127eb3 (diff)
Simplify queue membercount code
Despite an ominous sounding comment stating that membercount was for "logged in" members only and thus we couldn't use ao2_container_count(), I could not find a single place in the code where that seemed to be accurate. The only time we decremented membercount was when we were marking something dead or actually removing it. The only places we incremented it were either after ao2_link(), or trying to correct for having set it to 0 during a reload. In every case where we were correcting the value, it seemed that we were trying to make the count actually match what ao2_container_count() would return. The only place I could find where we made a determination about something being "logged in" or not, we didn't trust the membercount, but instead looked at devicestate, paused, etc. This patch removes membercount, replaces its use with ao2_container_count, and manually adds the results of ao2_container_count to a "membercount" field for ast_data queue query results. This patch also would fix AST-676, but as it is slightly riskier than the previously committed fix, the two commits have been made separately. Reivew: https://reviewboard.asterisk.org/r/1541/ ........ Merged revisions 342383 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 342384 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@342385 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r--apps/app_queue.c46
1 files changed, 9 insertions, 37 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index d8b8399c8..96012012d 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -1198,12 +1198,6 @@ struct call_queue {
int autofill; /*!< Ignore the head call status and ring an available agent */
struct ao2_container *members; /*!< Head of the list of members */
- /*!
- * \brief Number of members _logged in_
- * \note There will be members in the members container that are not logged
- * in, so this can not simply be replaced with ao2_container_count().
- */
- int membercount;
struct queue_ent *head; /*!< Head of the list of callers */
AST_LIST_ENTRY(call_queue) list; /*!< Next call queue */
AST_LIST_HEAD_NOLOCK(, penalty_rule) rules; /*!< The list of penalty rules to invoke */
@@ -2210,7 +2204,6 @@ static void rt_handle_member_record(struct call_queue *q, char *interface, struc
ao2_link(q->members, m);
ao2_ref(m, -1);
m = NULL;
- q->membercount++;
}
}
}
@@ -2225,7 +2218,6 @@ static void free_members(struct call_queue *q, int all)
while ((cur = ao2_iterator_next(&mem_iter))) {
if (all || !cur->dynamic) {
ao2_unlink(q->members, cur);
- q->membercount--;
}
ao2_ref(cur, -1);
}
@@ -2329,7 +2321,6 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as
ao2_lock(q);
clear_queue(q);
q->realtime = 1;
- q->membercount = 0;
/*Before we initialize the queue, we need to set the strategy, so that linear strategy
* will allocate the members properly
*/
@@ -2370,11 +2361,9 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as
queue_set_param(q, tmp_name, v->value, -1, 0);
}
- /* Temporarily set realtime members dead so we can detect deleted ones.
- * Also set the membercount correctly for realtime*/
+ /* Temporarily set realtime members dead so we can detect deleted ones. */
mem_iter = ao2_iterator_init(q->members, 0);
while ((m = ao2_iterator_next(&mem_iter))) {
- q->membercount++;
if (m->realtime) {
m->dead = 1;
}
@@ -2396,7 +2385,6 @@ static struct call_queue *find_queue_by_name_rt(const char *queuename, struct as
ast_queue_log(q->name, "REALTIME", m->membername, "REMOVEMEMBER", "%s", "");
}
ao2_unlink(q->members, m);
- q->membercount--;
}
ao2_ref(m, -1);
}
@@ -2516,7 +2504,6 @@ static void update_realtime_members(struct call_queue *q)
ast_queue_log(q->name, "REALTIME", m->membername, "REMOVEMEMBER", "%s", "");
}
ao2_unlink(q->members, m);
- q->membercount--;
}
ao2_ref(m, -1);
}
@@ -4169,7 +4156,8 @@ static int update_queue(struct call_queue *q, struct member *member, int callcom
static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
{
/* disregarding penalty on too few members? */
- unsigned char usepenalty = (q->membercount <= q->penaltymemberslimit) ? 0 : 1;
+ size_t membercount = ao2_container_count(q->members);
+ unsigned char usepenalty = (membercount <= q->penaltymemberslimit) ? 0 : 1;
if (usepenalty) {
if ((qe->max_penalty && (mem->penalty > qe->max_penalty)) ||
@@ -4178,7 +4166,7 @@ static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct
}
} else {
ast_debug(1, "Disregarding penalty, %d members and %d in penaltymemberslimit.\n",
- q->membercount, q->penaltymemberslimit);
+ membercount, q->penaltymemberslimit);
}
switch (q->strategy) {
@@ -4521,7 +4509,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_LINEAR || qe->parent->strategy == QUEUE_STRATEGY_RRORDERED)
(*tries)++;
else
- *tries = qe->parent->membercount;
+ *tries = ao2_container_count(qe->parent->members);
*noption = 1;
break;
case 'i':
@@ -5321,7 +5309,6 @@ static int remove_from_queue(const char *queuename, const char *interface)
queue_t_unref(q, "Interface wasn't dynamic, expiring temporary reference");
return RES_NOT_DYNAMIC;
}
- q->membercount--;
manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
"Queue: %s\r\n"
"Location: %s\r\n"
@@ -5368,7 +5355,6 @@ static int add_to_queue(const char *queuename, const char *interface, const char
if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface))) {
new_member->dynamic = 1;
ao2_link(q->members, new_member);
- q->membercount++;
manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
"Queue: %s\r\n"
"Location: %s\r\n"
@@ -6152,7 +6138,7 @@ check_turns:
}
/* exit after 'timeout' cycle if 'n' option enabled */
- if (noption && tries >= qe.parent->membercount) {
+ if (noption && tries >= ao2_container_count(qe.parent->members)) {
ast_verb(3, "Exiting on time-out cycle\n");
ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos);
record_abandoned(&qe);
@@ -6369,7 +6355,7 @@ static int queue_function_mem_read(struct ast_channel *chan, const char *cmd, ch
}
ao2_iterator_destroy(&mem_iter);
} else if (!strcasecmp(args.option, "count") || ast_strlen_zero(args.option)) {
- count = q->membercount;
+ count = ao2_container_count(q->members);
} else if (!strcasecmp(args.option, "penalty") && !ast_strlen_zero(args.interface) &&
((m = interface_exists(q, args.interface)))) {
count = m->penalty;
@@ -6870,11 +6856,6 @@ static void reload_single_member(const char *memberdata, struct call_queue *q)
if (cur) {
ao2_ref(cur, -1);
}
-
- /* Since this function is only called in a loop parsing all members after setting
- * q->membercount = 0 if we are reloading, we must increment the membercount whether
- * we add or reload, otherwise q->membercount stays 0 after a reload */
- q->membercount++;
}
static int mark_member_dead(void *obj, void *arg, int flags)
@@ -6889,19 +6870,11 @@ static int mark_member_dead(void *obj, void *arg, int flags)
static int kill_dead_members(void *obj, void *arg, int flags)
{
struct member *member = obj;
- struct call_queue *q = arg;
if (!member->delme) {
- if (member->dynamic) {
- /* dynamic members were not counted toward the member count
- * when reloading members from queues.conf, so we do that here
- */
- q->membercount++;
- }
member->status = get_queue_member_status(member);
return 0;
} else {
- q->membercount--;
return CMP_MATCH;
}
}
@@ -6980,7 +6953,6 @@ static void reload_single_queue(struct ast_config *cfg, struct ast_flags *mask,
init_queue(q);
}
if (member_reload) {
- q->membercount = 0;
ao2_callback(q->members, OBJ_NODATA, mark_member_dead, NULL);
}
for (var = ast_variable_browse(cfg, queuename); var; var = var->next) {
@@ -8371,8 +8343,7 @@ static struct ast_cli_entry cli_queue[] = {
MEMBER(call_queue, rrpos, AST_DATA_INTEGER) \
MEMBER(call_queue, memberdelay, AST_DATA_INTEGER) \
MEMBER(call_queue, autofill, AST_DATA_INTEGER) \
- MEMBER(call_queue, members, AST_DATA_CONTAINER) \
- MEMBER(call_queue, membercount, AST_DATA_INTEGER)
+ MEMBER(call_queue, members, AST_DATA_CONTAINER)
AST_DATA_STRUCTURE(call_queue, DATA_EXPORT_CALL_QUEUE);
@@ -8440,6 +8411,7 @@ static void queues_data_provider_get_helper(const struct ast_data_search *search
ast_data_add_structure(call_queue, data_queue, queue);
ast_data_add_str(data_queue, "strategy", int2strat(queue->strategy));
+ ast_data_add_int(data_queue, "membercount", ao2_container_count(queue->members));
/* announce position */
enum_node = ast_data_add_node(data_queue, "announceposition");