aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/app_queue.c15
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;
}