summaryrefslogtreecommitdiff
path: root/apps/app_queue.c
diff options
context:
space:
mode:
authorKevin Harwell <kharwell@digium.com>2015-09-17 11:31:15 -0500
committerKevin Harwell <kharwell@digium.com>2015-09-17 12:11:38 -0500
commit63ede41227fbcbedca366cb7f8359629be107a50 (patch)
tree291b14401b49860842d1b605664a6c48a1c06312 /apps/app_queue.c
parent0a74c803004c1c7d4d53aecc9e818b63d5a1e9d6 (diff)
app_queue: Crash when transferring
During some transfer scenarios involving queues Asterisk would sometimes crash when trying to obtain a channel snapshot (could happen on caller or member channels). This occurred because the underlying channel had already disappeared when trying to obtain the latest snapshot. This patch adds a reference to both the member and caller channels that extends to the lifetime of the queue'd call, thus making sure the channels will always exist when retrieving the latest snapshots. ASTERISK-25185 #close Reported by: Etienne Lessard Change-Id: Ic397fa68fb4ff35fbc378e745da9246a7b552128
Diffstat (limited to 'apps/app_queue.c')
-rw-r--r--apps/app_queue.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c
index bb3ec1790..cd9f5b01b 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -5582,6 +5582,10 @@ struct queue_stasis_data {
struct local_optimization caller_optimize;
/*! Local channel optimization details for the member */
struct local_optimization member_optimize;
+ /*! Member channel */
+ struct ast_channel *member_channel;
+ /*! Caller channel */
+ struct ast_channel *caller_channel;
};
/*!
@@ -5599,6 +5603,9 @@ static void queue_stasis_data_destructor(void *obj)
ao2_cleanup(queue_data->member);
queue_unref(queue_data->queue);
ast_string_field_free_memory(queue_data);
+
+ ao2_ref(queue_data->member_channel, -1);
+ ao2_ref(queue_data->caller_channel, -1);
}
/*!
@@ -5645,6 +5652,16 @@ static struct queue_stasis_data *queue_stasis_data_alloc(struct queue_ent *qe,
queue_data->caller_pos = qe->opos;
ao2_ref(mem, +1);
queue_data->member = mem;
+
+ /*
+ * During transfers it's possible for both the member and/or caller
+ * channel(s) to not be available. Adding a reference here ensures
+ * that the channels remain until app_queue is completely done with
+ * them.
+ */
+ queue_data->member_channel = ao2_bump(peer);
+ queue_data->caller_channel = ao2_bump(qe->chan);
+
return queue_data;
}