mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 23:08:32 +00:00
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: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@231559 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -661,6 +661,11 @@ static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, st
|
|||||||
q->head = new;
|
q->head = new;
|
||||||
}
|
}
|
||||||
new->next = cur;
|
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->parent = q;
|
||||||
new->pos = ++(*pos);
|
new->pos = ++(*pos);
|
||||||
new->opos = *pos;
|
new->opos = *pos;
|
||||||
@@ -4848,7 +4853,7 @@ static int queue_exec(struct ast_channel *chan, void *data)
|
|||||||
AST_APP_ARG(rule);
|
AST_APP_ARG(rule);
|
||||||
);
|
);
|
||||||
/* Our queue entry */
|
/* Our queue entry */
|
||||||
struct queue_ent qe;
|
struct queue_ent qe = { 0 };
|
||||||
|
|
||||||
if (ast_strlen_zero(data)) {
|
if (ast_strlen_zero(data)) {
|
||||||
ast_log(LOG_WARNING, "Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,macro[,gosub[,rule]]]]]]]]\n");
|
ast_log(LOG_WARNING, "Queue requires an argument: queuename[,options[,URL[,announceoverride[,timeout[,agi[,macro[,gosub[,rule]]]]]]]]\n");
|
||||||
@@ -4859,7 +4864,6 @@ static int queue_exec(struct ast_channel *chan, void *data)
|
|||||||
AST_STANDARD_APP_ARGS(args, parse);
|
AST_STANDARD_APP_ARGS(args, parse);
|
||||||
|
|
||||||
/* Setup our queue entry */
|
/* Setup our queue entry */
|
||||||
memset(&qe, 0, sizeof(qe));
|
|
||||||
qe.start = time(NULL);
|
qe.start = time(NULL);
|
||||||
|
|
||||||
/* set the expire time based on the supplied timeout; */
|
/* set the expire time based on the supplied timeout; */
|
||||||
@@ -5120,6 +5124,13 @@ stop:
|
|||||||
if (reason != QUEUE_UNKNOWN)
|
if (reason != QUEUE_UNKNOWN)
|
||||||
set_queue_result(chan, reason);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user