diff --git a/apps/app_queue.c b/apps/app_queue.c index ddcbc4b2675926226491ac43e5ac275515efc417..9edb704c375702a7a115497d4cd927a62e7227a8 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -300,10 +300,18 @@ const struct { /*! \brief We define a custom "local user" structure because we use it not only for keeping track of what is in use but - also for keeping track of who we're dialing. */ + also for keeping track of who we're dialing. + + There are two "links" defined in this structure, q_next and call_next. + q_next links ALL defined callattempt structures into a linked list. call_next is + a link which allows for a subset of the callattempts to be traversed. This subset + is used in wait_for_answer so that irrelevant callattempts are not traversed. This + also is helpful so that queue logs are always accurate in the case where a call to + a member times out, especially if using the ringall strategy. */ struct callattempt { struct callattempt *q_next; + struct callattempt *call_next; struct ast_channel *chan; char interface[256]; int stillgoing; @@ -2303,7 +2311,7 @@ static void rna(int rnatime, struct queue_ent *qe, char *interface, char *member static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed) { const char *queue = qe->parent->name; - struct callattempt *o; + struct callattempt *o, *start = NULL, *prev = NULL; int status; int numbusies = prebusies; int numnochan = 0; @@ -2333,14 +2341,21 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte int numlines, retry, pos = 1; struct ast_channel *watchers[AST_MAX_WATCHERS]; watchers[0] = in; + start = NULL; for (retry = 0; retry < 2; retry++) { numlines = 0; for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */ if (o->stillgoing) { /* Keep track of important channels */ stillgoing = 1; - if (o->chan) + if (o->chan) { watchers[pos++] = o->chan; + if (!start) + start = o; + else + prev->call_next = o; + prev = o; + } } numlines++; } @@ -2362,7 +2377,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte return NULL; } winner = ast_waitfor_n(watchers, pos, to); - for (o = outgoing; o; o = o->q_next) { + for (o = start; o; o = o->call_next) { if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) { if (!peer) { ast_verb(3, "%s answered %s\n", o->chan->name, in->name); @@ -2524,8 +2539,10 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte } ast_frfree(f); } - if (!*to) - rna(orig, qe, on, membername); + if (!*to) { + for (o = start; o; o = o->call_next) + rna(orig, qe, o->interface, o->member->membername); + } } #ifdef HAVE_EPOLL