]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 231556 via svnmerge from
authorDavid Vossel <dvossel@digium.com>
Mon, 30 Nov 2009 18:58:05 +0000 (18:58 +0000)
committerDavid Vossel <dvossel@digium.com>
Mon, 30 Nov 2009 18:58:05 +0000 (18:58 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

........
  r231556 | dvossel | 2009-11-30 12:55:07 -0600 (Mon, 30 Nov 2009) | 11 lines

  app_queue crashes randomly, often during call-transfers

  This patch adds a ref to the queue_ent object's parent call_queue
  in queue_exec() so the call_queue won't be destroyed
  while the the queue_ent still holds a pointer to it.

  (closes issue 0015686)
  Tested by: dvossel, aragon
........

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

apps/app_queue.c

index 351e6b3319ae34d53842c9ed4c0ba87e5739728d..1a8b3b0f740844b03ea347878fa1048e89b4d68d 100644 (file)
@@ -626,6 +626,11 @@ static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, st
                q->head = new;
        }
        new->next = cur;
+
+       /* every queue_ent must have a reference to it's parent call_queue, this
+        * reference does not go away until the end of the queue_ent's life, meaning
+        * that even when the queue_ent leaves the call_queue this ref must remain. */
+       queue_ref(q);
        new->parent = q;
        new->pos = ++(*pos);
        new->opos = *pos;
@@ -4766,7 +4771,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
                AST_APP_ARG(rule);
        );
        /* Our queue entry */
-       struct queue_ent qe;
+       struct queue_ent qe = { 0 };
        
        if (ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,macro[,gosub[,rule]]]]]]]]\n");
@@ -4777,7 +4782,6 @@ static int queue_exec(struct ast_channel *chan, void *data)
        AST_STANDARD_APP_ARGS(args, parse);
 
        /* Setup our queue entry */
-       memset(&qe, 0, sizeof(qe));
        qe.start = time(NULL);
 
        /* set the expire time based on the supplied timeout; */
@@ -5036,6 +5040,13 @@ stop:
        if (reason != QUEUE_UNKNOWN)
                set_queue_result(chan, reason);
 
+       if (qe.parent) {
+               /* every queue_ent is given a reference to it's parent call_queue when it joins the queue.
+                * This ref must be taken away right before the queue_ent is destroyed.  In this case
+                * the queue_ent is about to be returned on the stack */
+               qe.parent = queue_unref(qe.parent);
+       }
+
        return res;
 }