From 0f8f6e239e76695d6e8c8544ab552b9fb93612f5 Mon Sep 17 00:00:00 2001
From: Mark Michelson <mmichelson@digium.com>
Date: Fri, 28 Mar 2008 00:12:52 +0000
Subject: [PATCH] Fix a crash that would happen when attempting to unload the
 app_queue module.

The problem was that when the refcount on the queue hit 0, the destructor was
called, and inside the destructor, another function was called which would increase
the refcount back to 1 again and then decrease it again back to 0 for every member
in the queue. This meant that the destructor was being recursively called, leading
to a double free of the queue. This is now fixed by making sure to unlink the
queue from the queues container prior to the final unref of the queue.



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@111533 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 apps/app_queue.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/apps/app_queue.c b/apps/app_queue.c
index 3c3a2cff78..ca67f0a9f2 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -1409,8 +1409,6 @@ static void destroy_queue(void *obj)
 	struct call_queue *q = obj;
 	int i;
 
-	ast_debug(0, "Queue destructor called for queue '%s'!\n", q->name);
-
 	free_members(q, 1);
 	ast_string_field_free_memory(q);
 	for (i = 0; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
@@ -6178,6 +6176,8 @@ static int unload_module(void)
 {
 	int res;
 	struct ast_context *con;
+	struct ao2_iterator q_iter;
+	struct call_queue *q = NULL;
 
 	if (device_state.thread != AST_PTHREADT_NULL) {
 		device_state.stop = 1;
@@ -6220,6 +6220,11 @@ static int unload_module(void)
 
 	clear_and_free_interfaces();
 
+	q_iter = ao2_iterator_init(queues, 0);
+	while ((q = ao2_iterator_next(&q_iter))) {
+		ao2_unlink(queues, q);
+		queue_unref(q);
+	}
 	ao2_ref(queues, -1);
 
 	return res;
-- 
GitLab