Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 35942) +++ apps/app_queue.c (working copy) @@ -99,7 +99,8 @@ QUEUE_STRATEGY_LEASTRECENT, QUEUE_STRATEGY_FEWESTCALLS, QUEUE_STRATEGY_RANDOM, - QUEUE_STRATEGY_RRMEMORY + QUEUE_STRATEGY_RRMEMORY, + QUEUE_STRATEGY_LINEAR }; static struct strategy { @@ -112,6 +113,7 @@ { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" }, { QUEUE_STRATEGY_RANDOM, "random" }, { QUEUE_STRATEGY_RRMEMORY, "rrmemory" }, + { QUEUE_STRATEGY_LINEAR, "linear" }, }; #define DEFAULT_RETRY 5 @@ -2198,6 +2200,8 @@ /* Everyone equal, except for penalty */ tmp->metric = mem->penalty * 1000000; break; + case QUEUE_STRATEGY_LINEAR: + /* Fall through */ case QUEUE_STRATEGY_ROUNDROBIN: if (!pos) { if (!q->wrapped) { @@ -2243,6 +2247,20 @@ return 0; } +static void reset_rrpos(struct queue_ent *qe) { + + /* Reset the RoundRobin position counter + whilst agent has answered or user has hangup. */ + if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) { + ast_mutex_lock(&qe->parent->lock); + ast_log(LOG_WARNING, "LINEAR: Resetting RRPOS!\n"); + qe->parent->rrpos = 0; + qe->parent->wrapped = 0; + ast_mutex_unlock(&qe->parent->lock); + } + +} + static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on, const char *agi) { struct member *cur; @@ -2386,6 +2404,7 @@ if (!strcmp(peer->tech->type, "Zap")) ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0); /* Update parameters for the queue */ + reset_rrpos(qe); recalc_holdtime(qe); member = lpeer->member; hangupcalls(outgoing, peer); @@ -3412,6 +3431,9 @@ } } } + + reset_rrpos(&qe); + /* Don't allow return code > 0 */ if (res >= 0 && res != AST_PBX_KEEPALIVE) { res = 0; @@ -3660,6 +3682,13 @@ /* Re-initialize the queue, and clear statistics */ init_queue(q); clear_queue(q); + + if (q->strategy == QUEUE_STRATEGY_LINEAR) { + /* free static members in linear mode, to get a sorted + list like defined in config */ + free_members(q, (int) !queue_persistent_members); + } + for (cur = q->members; cur; cur = cur->next) { if (!cur->dynamic) { cur->delme = 1;