[asterisk-commits] tilghman: branch 1.6.1 r231135 - in /branches/1.6.1: ./ apps/app_queue.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Nov 24 14:35:06 CST 2009


Author: tilghman
Date: Tue Nov 24 14:35:02 2009
New Revision: 231135

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=231135
Log:
Merged revisions 231134 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r231134 | tilghman | 2009-11-24 14:31:28 -0600 (Tue, 24 Nov 2009) | 7 lines
  
  Found a few places where queue refcounts were counted incorrectly.  Also add debug statements.
  (closes issue #15982, closes issue #15984)
   Reported by: atis
   Patches: 
         20091111__issue15982.diff.txt uploaded by tilghman (license 14)
   Tested by: atis
........

Modified:
    branches/1.6.1/   (props changed)
    branches/1.6.1/apps/app_queue.c

Propchange: branches/1.6.1/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.1/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.1/apps/app_queue.c?view=diff&rev=231135&r1=231134&r2=231135
==============================================================================
--- branches/1.6.1/apps/app_queue.c (original)
+++ branches/1.6.1/apps/app_queue.c Tue Nov 24 14:35:02 2009
@@ -94,6 +94,8 @@
 #include "asterisk/strings.h"
 #include "asterisk/global_datastores.h"
 #include "asterisk/taskprocessor.h"
+
+#define REF_DEBUG_ONLY_QUEUES
 
 /*!
  * \par Please read before modifying this file.
@@ -600,6 +602,18 @@
 	return !strcasecmp(q->name, q2->name) ? CMP_MATCH | CMP_STOP : 0;
 }
 
+#ifdef REF_DEBUG_ONLY_QUEUES
+#define queue_ref(a)	_ao2_ref_debug(a,1,"",__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#define queue_unref(a)	_ao2_ref_debug(a,-1,"",__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#define queue_t_ref(a,b)	_ao2_ref_debug(a,1,b,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#define queue_t_unref(a,b)	_ao2_ref_debug(a,-1,b,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#define queues_t_link(c,q,tag)	_ao2_link_debug(c,q,tag,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#define queues_t_unlink(c,q,tag)	_ao2_unlink_debug(c,q,tag,__FILE__,__LINE__,__PRETTY_FUNCTION__)
+#else
+#define queue_t_ref(a,b)	queue_ref(a)
+#define queue_t_unref(a,b)	queue_unref(a)
+#define queues_t_link(c,q,tag)	ao2_t_link(c,q,tag)
+#define queues_t_unlink(c,q,tag)	ao2_t_unlink(c,q,tag)
 static inline struct call_queue *queue_ref(struct call_queue *q)
 {
 	ao2_ref(q, 1);
@@ -611,6 +625,7 @@
 	ao2_ref(q, -1);
 	return q;
 }
+#endif
 
 /*! \brief Set variables of queue */
 static void set_queue_variables(struct call_queue *q, struct ast_channel *chan)
@@ -721,7 +736,7 @@
 	char tmp_interface[80];
 
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((cur = ao2_iterator_next(&mem_iter))) {
@@ -758,7 +773,7 @@
 			}
 			ao2_ref(cur, -1);
 		}
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 		ao2_unlock(q);
 	}
 
@@ -995,7 +1010,7 @@
 
 	ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
 	queue_iter = ao2_iterator_init(queues, lock_queue_container ? 0 : AO2_ITERATOR_DONTLOCK);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((mem = ao2_iterator_next(&mem_iter))) { 
@@ -1007,7 +1022,7 @@
 		}
 		ao2_iterator_destroy(&mem_iter);
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -1442,9 +1457,9 @@
 {
 	struct call_queue *q;
 
-	if ((q = ao2_alloc(sizeof(*q), destroy_queue))) {
+	if ((q = ao2_t_alloc(sizeof(*q), destroy_queue, "Allocate queue"))) {
 		if (ast_string_field_init(q, 64)) {
-			ao2_ref(q, -1);
+			ao2_t_ref(q, -1, "String field allocation failed");
 			return NULL;
 		}
 		ast_string_field_set(q, name, queuename);
@@ -1476,12 +1491,12 @@
 	char tmpbuf[64];	/* Must be longer than the longest queue param name. */
 
 	/* Static queues override realtime. */
-	if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+	if ((q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Check if static queue exists"))) {
 		ao2_lock(q);
 		if (!q->realtime) {
 			if (q->dead) {
 				ao2_unlock(q);
-				queue_unref(q);
+				queue_t_unref(q, "Queue is dead; can't return it");
 				return NULL;
 			} else {
 				ast_log(LOG_WARNING, "Static queue '%s' already exists. Not loading from realtime\n", q->name);
@@ -1489,7 +1504,6 @@
 				return q;
 			}
 		}
-		queue_unref(q);
 	} else if (!member_config)
 		/* Not found in the list, and it's not realtime ... */
 		return NULL;
@@ -1505,9 +1519,9 @@
 
 			q->dead = 1;
 			/* Delete if unused (else will be deleted when last caller leaves). */
-			ao2_unlink(queues, q);
+			queues_t_unlink(queues, q, "Unused, removing from container");
 			ao2_unlock(q);
-			queue_unref(q);
+			queue_t_unref(q, "Queue is dead; can't return it");
 		}
 		return NULL;
 	}
@@ -1537,7 +1551,7 @@
 		/* We traversed all variables and didn't find a strategy */
 		if (!tmpvar)
 			q->strategy = QUEUE_STRATEGY_RINGALL;
-		ao2_link(queues, q);
+		queues_t_link(queues, q, "Add queue to container");
 	}
 	init_queue(q);		/* Ensure defaults for all parameters not set explicitly. */
 
@@ -1606,7 +1620,7 @@
 	};
 
 	/* Find the queue in the in-core list first. */
-	q = ao2_find(queues, &tmpq, OBJ_POINTER);
+	q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Look for queue in memory first");
 
 	if (!q || q->realtime) {
 		/*! \note Load from realtime before taking the "queues" container lock, to avoid blocking all
@@ -2016,7 +2030,7 @@
 
 	if (!(q = qe->parent))
 		return;
-	queue_ref(q);
+	queue_t_ref(q, "Copy queue pointer from queue entry");
 	ao2_lock(q);
 
 	prev = NULL;
@@ -2057,10 +2071,10 @@
 
 	if (q->dead) {	
 		/* It's dead and nobody is in it, so kill it */
-		ao2_unlink(queues, q);
+		queues_t_unlink(queues, q, "Queue is now dead; remove it from the container");
 	}
 	/* unref the explicit ref earlier in the function */
-	queue_unref(q);
+	queue_t_unref(q, "Expire copied reference");
 }
 
 /*! \brief Hang up a list of outgoing calls */
@@ -2141,9 +2155,9 @@
 	/* q's lock and rq's lock already set by try_calling()
 	 * to solve deadlock */
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		if (q == rq) { /* don't check myself, could deadlock */
-			queue_unref(q);
+			queue_t_unref(q, "Done with iterator");
 			continue;
 		}
 		ao2_lock(q);
@@ -2158,7 +2172,7 @@
 			}
 		}
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 		if (found) {
 			break;
 		}
@@ -3064,7 +3078,7 @@
 	
 	if (shared_lastcall) {
 		queue_iter = ao2_iterator_init(queues, 0);
-		while ((qtmp = ao2_iterator_next(&queue_iter))) {
+		while ((qtmp = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 			ao2_lock(qtmp);
 			if ((mem = ao2_find(qtmp->members, member, OBJ_POINTER))) {
 				time(&mem->lastcall);
@@ -3318,7 +3332,7 @@
 		set_queue_variables(q, chan);
 		ao2_unlock(q);
 		/* This unrefs the reference we made in try_calling when we allocated qeb */
-		queue_unref(q);
+		queue_t_unref(q, "Expire bridge_config reference");
 	}
 }
 
@@ -4041,7 +4055,7 @@
 			 * to make sure to increase the refcount of this queue so it cannot be freed until we
 			 * are done with it. We remove this reference in end_bridge_callback.
 			 */
-			queue_ref(qe->parent);
+			queue_t_ref(qe->parent, "For bridge_config reference");
 		}
 
 		time(&callstart);
@@ -4184,7 +4198,7 @@
 	int res = RES_NOSUCHQUEUE;
 
 	ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
-	if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+	if ((q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Temporary reference for interface removal"))) {
 		ao2_lock(queues);
 		ao2_lock(q);
 		if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
@@ -4192,7 +4206,7 @@
 			if (!mem->dynamic) {
 				ao2_ref(mem, -1);
 				ao2_unlock(q);
-				queue_unref(q);
+				queue_t_unref(q, "Interface wasn't dynamic, expiring temporary reference");
 				ao2_unlock(queues);
 				return RES_NOT_DYNAMIC;
 			}
@@ -4215,7 +4229,7 @@
 		}
 		ao2_unlock(q);
 		ao2_unlock(queues);
-		queue_unref(q);
+		queue_t_unref(q, "Expiring temporary reference");
 	}
 
 	return res;
@@ -4297,7 +4311,7 @@
 		ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
 
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 		if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
 			if ((mem = interface_exists(q, interface))) {
@@ -4314,6 +4328,7 @@
 					ast_log(LOG_WARNING, "Failed %spausing realtime queue member %s:%s\n", (paused ? "" : "un"), q->name, interface);
 					ao2_ref(mem, -1);
 					ao2_unlock(q);
+					queue_t_unref(q, "Done with iterator");
 					continue;
 				}	
 				found++;
@@ -4346,12 +4361,12 @@
 		
 		if (!ast_strlen_zero(queuename) && !strcasecmp(queuename, q->name)) {
 			ao2_unlock(q);
-			queue_unref(q);
+			queue_t_unref(q, "Done with iterator");
 			break;
 		}
 		
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -4372,7 +4387,7 @@
 	}
 
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 		if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
 			foundqueue++;
@@ -4390,7 +4405,7 @@
 			}
 		}
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -4416,18 +4431,18 @@
 	};
 	struct member *mem;
 	
-	if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+	if ((q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Search for queue"))) {
 		foundqueue = 1;
 		ao2_lock(q);
 		if ((mem = interface_exists(q, interface))) {
 			penalty = mem->penalty;
 			ao2_ref(mem, -1);
 			ao2_unlock(q);
-			queue_unref(q);
+			queue_t_unref(q, "Search complete");
 			return penalty;
 		}
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Search complete");
 	}
 
 	/* some useful debuging */
@@ -4469,7 +4484,7 @@
 			struct call_queue tmpq = {
 				.name = queue_name,
 			};
-			cur_queue = ao2_find(queues, &tmpq, OBJ_POINTER);
+			cur_queue = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Reload queue members");
 		}	
 
 		if (!cur_queue)
@@ -4484,7 +4499,7 @@
 		} 
 
 		if (ast_db_get(pm_family, queue_name, queue_data, PM_MAX_LEN)) {
-			queue_unref(cur_queue);
+			queue_t_unref(cur_queue, "Expire reload reference");
 			continue;
 		}
 
@@ -4526,7 +4541,7 @@
 				break;
 			}
 		}
-		queue_unref(cur_queue);
+		queue_t_unref(cur_queue, "Expire reload reference");
 	}
 
 	ao2_unlock(queues);
@@ -5128,7 +5143,7 @@
 		return -1;
 	}
 
-	if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+	if ((q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Find for QUEUE() function"))) {
 		ao2_lock(q);
 		if (q->setqueuevar) {
 			sl = 0;
@@ -5146,7 +5161,7 @@
 		}
 
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with temporary reference in QUEUE() function");
 	} else {
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 	}
@@ -5203,7 +5218,7 @@
 		} else /* must be "count" */
 			count = q->membercount;
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER()");
 	} else
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 
@@ -5247,7 +5262,7 @@
 		}
 		ao2_iterator_destroy(&mem_iter);
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER_COUNT");
 	} else
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 
@@ -5272,11 +5287,11 @@
 		return -1;
 	}
 
-	if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+	if ((q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Find for QUEUE_WAITING_COUNT()"))) {
 		ao2_lock(q);
 		count = q->count;
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with find for QUEUE_WAITING_COUNT");
 	} else if ((var = ast_load_realtime("queues", "name", data, SENTINEL))) {
 		/* if the queue is realtime but was not found in memory, this
 		 * means that the queue had been deleted from memory since it was 
@@ -5308,7 +5323,7 @@
 		return -1;
 	}
 
-	if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+	if ((q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Find for QUEUE_MEMBER_LIST()"))) {
 		int buflen = 0, count = 0;
 		struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
 
@@ -5331,7 +5346,7 @@
 		}
 		ao2_iterator_destroy(&mem_iter);
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with find for QUEUE_MEMBER_LIST()");
 	} else
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 
@@ -5560,12 +5575,12 @@
 	use_weight=0;
 	/* Mark all queues as dead for the moment */
 	queue_iter = ao2_iterator_init(queues, AO2_ITERATOR_DONTLOCK);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		if (!q->realtime) {
 			q->dead = 1;
 			q->found = 0;
 		}
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 
 	/* Chug through config file */
@@ -5598,7 +5613,7 @@
 			struct call_queue tmpq = {
 				.name = cat,
 			};
-			if (!(q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
+			if (!(q = ao2_t_find(queues, &tmpq, OBJ_POINTER, "Verify whether we exist or not"))) {
 				/* Make one then */
 				if (!(q = alloc_queue(cat))) {
 					/* TODO: Handle memory allocation failure */
@@ -5615,7 +5630,7 @@
 					ast_log(LOG_WARNING, "Queue '%s' already defined! Skipping!\n", cat);
 					if (!new) {
 						ao2_unlock(q);
-						queue_unref(q);
+						queue_t_unref(q, "We exist! Expiring temporary pointer");
 					}
 					continue;
 				}
@@ -5720,18 +5735,18 @@
 				}
 
 				if (new) {
-					ao2_link(queues, q);
+					queues_t_link(queues, q, "Add queue to container");
 				} else 
 					ao2_unlock(q);
-				queue_unref(q);
+				queue_t_unref(q, "Added queue to container, deleting creation pointer");
 			}
 		}
 	}
 	ast_config_destroy(cfg);
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		if (q->dead) {
-			ao2_unlink(queues, q);
+			queues_t_unlink(queues, q, "Remove queue from container because marked as dead");
 		} else {
 			ao2_lock(q);
 			mem_iter = ao2_iterator_init(q->members, 0);
@@ -5743,7 +5758,7 @@
 			}
 			ao2_unlock(q);
 		}
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_unlock(queues);
 	return 1;
@@ -5778,7 +5793,7 @@
 
 	if (argc == 3)	{ /* specific queue */
 		if ((q = load_realtime_queue(argv[2]))) {
-			queue_unref(q);
+			queue_t_unref(q, "Expiring queue loaded from realtime");
 		}
 	} else if (ast_check_realtime("queues")) {
 		/* This block is to find any queues which are defined in realtime but
@@ -5789,7 +5804,7 @@
 		if (cfg) {
 			for (queuename = ast_category_browse(cfg, NULL); !ast_strlen_zero(queuename); queuename = ast_category_browse(cfg, queuename)) {
 				if ((q = load_realtime_queue(queuename))) {
-					queue_unref(q);
+					queue_t_unref(q, "Expiring queue loaded from realtime");
 				}
 			}
 			ast_config_destroy(cfg);
@@ -5798,7 +5813,7 @@
 
 	queue_iter = ao2_iterator_init(queues, AO2_ITERATOR_DONTLOCK);
 	ao2_lock(queues);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		float sl;
 		struct call_queue *realtime_queue = NULL;
 
@@ -5809,14 +5824,14 @@
 		 */
 		if (q->realtime && !(realtime_queue = load_realtime_queue(q->name))) {
 			ao2_unlock(q);
-			queue_unref(q);
+			queue_t_unref(q, "Done with iterator");
 			continue;
 		} else if (q->realtime) {
-			queue_unref(realtime_queue);
+			queue_t_unref(realtime_queue, "Expire queue loaded from realtime");
 		}
 		if (argc == 3 && strcasecmp(q->name, argv[2])) {
 			ao2_unlock(q);
-			queue_unref(q);
+			queue_t_unref(q, "Done with iterator");
 			continue;
 		}
 		found = 1;
@@ -5878,7 +5893,7 @@
 		}
 		do_print(s, fd, "");	/* blank line between entries */
 		ao2_unlock(q);
-		queue_unref(q); /* Unref the iterator's reference */
+		queue_t_unref(q, "Done with iterator"); /* Unref the iterator's reference */
 	}
 	ao2_iterator_destroy(&queue_iter);
 	ao2_unlock(queues);
@@ -5901,13 +5916,13 @@
 	struct ao2_iterator queue_iter;
 
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		if (!strncasecmp(word, q->name, wordlen) && ++which > state) {
 			ret = ast_strdup(q->name);
-			queue_unref(q);
+			queue_t_unref(q, "Done with iterator");
 			break;
 		}
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -5996,7 +6011,7 @@
 	if (!ast_strlen_zero(id))
 		snprintf(idText, 256, "ActionID: %s\r\n", id);
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 
 		/* List queue properties */
@@ -6037,7 +6052,7 @@
 				q->name, qmemcount, qmemavail, qchancount, q->holdtime, qlongestholdtime, idText);
 		}
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 	astman_append(s,
@@ -6070,7 +6085,7 @@
 		snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
 
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 
 		/* List queue properties */
@@ -6132,7 +6147,7 @@
 			}
 		}
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -6424,7 +6439,7 @@
 
 	/* here is the case for 3, <member> */
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate through queues"))) {
 		ao2_lock(q);
 		mem_iter = ao2_iterator_init(q->members, 0);
 		while ((m = ao2_iterator_next(&mem_iter))) {
@@ -6433,7 +6448,7 @@
 				ao2_unlock(q);
 				tmp = ast_strdup(m->interface);
 				ao2_ref(m, -1);
-				queue_unref(q);
+				queue_t_unref(q, "Done with iterator");
 				ao2_iterator_destroy(&mem_iter);
 				ao2_iterator_destroy(&queue_iter);
 				return tmp;
@@ -6442,7 +6457,7 @@
 		}
 		ao2_iterator_destroy(&mem_iter);
 		ao2_unlock(q);
-		queue_unref(q);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -6757,9 +6772,9 @@
 	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);
+	while ((q = ao2_t_iterator_next(&q_iter, "Iterate through queues"))) {
+		queues_t_unlink(queues, q, "Remove queue from container due to unload");
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&q_iter);
 	ao2_ref(queues, -1);




More information about the asterisk-commits mailing list