Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 75446) +++ apps/app_queue.c (working copy) @@ -395,6 +395,7 @@ int autofill; /*!< Ignore the head call status and ring an available agent */ struct member *members; /*!< Head of the list of members */ + int membercount; /*!< Number of members in queue */ struct queue_ent *head; /*!< Head of the list of callers */ AST_LIST_ENTRY(call_queue) list; /*!< Next call queue */ }; @@ -665,6 +666,7 @@ q->context[0] = '\0'; q->monfmt[0] = '\0'; q->periodicannouncefrequency = 0; + q->membercount = 0; ast_copy_string(q->sound_next, "queue-youarenext", sizeof(q->sound_next)); ast_copy_string(q->sound_thereare, "queue-thereare", sizeof(q->sound_thereare)); ast_copy_string(q->sound_calls, "queue-callswaiting", sizeof(q->sound_calls)); @@ -957,6 +959,7 @@ } else { q->members = m; } + q->membercount++; } } else { m->dead = 0; /* Do not delete this one. */ @@ -979,6 +982,7 @@ else q->members = next; remove_from_interfaces(curm->interface); + q->membercount--; free(curm); } else prev = curm; @@ -1101,6 +1105,7 @@ q->members = next_m; } remove_from_interfaces(m->interface); + q->membercount--; free(m); } else { prev_m = m; @@ -2356,7 +2361,10 @@ ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT); break; case 'n': - *go_on = 1; + if (qe->parent->strategy == QUEUE_STRATEGY_ROUNDROBIN || qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) + (*go_on)++; + else + *go_on = qe->parent->membercount; break; case 'i': forwardsallowed = 0; @@ -2780,10 +2788,12 @@ if ((last_member = interface_exists(q, interface))) { if ((look = q->members) == last_member) { q->members = last_member->next; + q->membercount--; } else { while (look != NULL) { if (look->next == last_member) { look->next = last_member->next; + q->membercount--; break; } else { look = look->next; @@ -2837,6 +2847,7 @@ new_member->dynamic = 1; new_member->next = q->members; q->members = new_member; + q->membercount++; manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded", "Queue: %s\r\n" "Location: %s\r\n" @@ -3471,7 +3482,8 @@ stat = get_member_status(qe.parent, qe.max_penalty); /* exit after 'timeout' cycle if 'n' option enabled */ - if (go_on) { + if (go_on >= qe.parent->membercount) { + ast_log(LOG_DEBUG, "Timing out from \'n\' option since we have rung %d phones and there are %d queue members\n", go_on, q->membercount); if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Exiting on time-out cycle\n"); ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHTIMEOUT", "%d", qe.pos); @@ -3564,7 +3576,6 @@ int count = 0; struct call_queue *q; struct ast_module_user *lu; - struct member *m; buf[0] = '\0'; @@ -3585,12 +3596,7 @@ AST_LIST_UNLOCK(&queues); if (q) { - for (m = q->members; m; m = m->next) { - /* Count the agents who are logged in and presently answering calls */ - if ((m->status != AST_DEVICE_UNAVAILABLE) && (m->status != AST_DEVICE_INVALID)) { - count++; - } - } + count = q->membercount; ast_mutex_unlock(&q->lock); } else ast_log(LOG_WARNING, "queue %s was not found\n", data); @@ -3843,6 +3849,7 @@ newm->next = q->members; q->members = newm; } + q->membercount++; } else { queue_set_param(q, var->name, var->value, var->lineno, 1); } @@ -3865,6 +3872,7 @@ q->members = next; remove_from_interfaces(cur->interface); + q->membercount--; free(cur); }