diff options
author | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-11-30 18:58:05 +0000 |
---|---|---|
committer | dvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-11-30 18:58:05 +0000 |
commit | d41c7baaf027c73d3c769e2223bc010af69cbd04 (patch) | |
tree | b85afde2ae2e02589e4e75d422fef285c97761de | |
parent | 31cf4dfb4e11c80b897b031bbb305a9730aac88f (diff) |
Merged revisions 231556 via svnmerge from
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: http://svn.digium.com/svn/asterisk/branches/1.6.0@231560 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | apps/app_queue.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 351e6b331..1a8b3b0f7 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -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; } |