]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 95890 via svnmerge from
authorMark Michelson <mmichelson@digium.com>
Wed, 2 Jan 2008 18:05:57 +0000 (18:05 +0000)
committerMark Michelson <mmichelson@digium.com>
Wed, 2 Jan 2008 18:05:57 +0000 (18:05 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r95890 | mmichelson | 2008-01-02 11:51:22 -0600 (Wed, 02 Jan 2008) | 9 lines

A change to improve the accuracy of queue logging in the case where a member does not
answer during the specified timeout period. Prior to this change, there was a small chance
that the member name recorded in this case would be blank. Also prior to this change, if using
the ringall strategy, if no one answered the call during the specified timeout, the member name
listed in the queue log would randomly be one of the members that was rung.

(closes issue #11498, reported and tested by hloubser, patched by me)

........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@95891 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_queue.c

index ddcbc4b2675926226491ac43e5ac275515efc417..9edb704c375702a7a115497d4cd927a62e7227a8 100644 (file)
@@ -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