[asterisk-commits] irroot: branch irroot/distrotech-customers-trunk r342013 - in /team/irroot/di...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun Oct 23 13:41:03 CDT 2011


Author: irroot
Date: Sun Oct 23 13:41:00 2011
New Revision: 342013

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=342013
Log:
Commit state fixup for app_queue RB1538

Modified:
    team/irroot/distrotech-customers-trunk/   (props changed)
    team/irroot/distrotech-customers-trunk/CHANGES
    team/irroot/distrotech-customers-trunk/apps/app_queue.c

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
Binary property 'branch-10-merged' - no diff available.

Propchange: team/irroot/distrotech-customers-trunk/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Sun Oct 23 13:41:00 2011
@@ -1,1 +1,1 @@
-/trunk:1-341877
+/trunk:1-342009

Modified: team/irroot/distrotech-customers-trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/CHANGES?view=diff&rev=342013&r1=342012&r2=342013
==============================================================================
--- team/irroot/distrotech-customers-trunk/CHANGES (original)
+++ team/irroot/distrotech-customers-trunk/CHANGES Sun Oct 23 13:41:00 2011
@@ -261,8 +261,6 @@
  * Added member option ignorebusy this when set and ringinuse is not
    will allow per member control of multiple calls as ringinuse does for
    the Queue.
- * Added global option check_state_unknown to enforce checking of device state
-   when the device state is unknown app_queue will see unknown as available.
 
 Applications
 ------------

Modified: team/irroot/distrotech-customers-trunk/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/irroot/distrotech-customers-trunk/apps/app_queue.c?view=diff&rev=342013&r1=342012&r2=342013
==============================================================================
--- team/irroot/distrotech-customers-trunk/apps/app_queue.c (original)
+++ team/irroot/distrotech-customers-trunk/apps/app_queue.c Sun Oct 23 13:41:00 2011
@@ -1058,14 +1058,14 @@
 	int penalty;                         /*!< Are we a last resort? */
 	int calls;                           /*!< Number of calls serviced by this member */
 	int dynamic;                         /*!< Are we dynamically added? */
-	int realtime:1;                      /*!< Is this member realtime? */
-	int paused:1;                        /*!< Are we paused (not accepting calls)? */
 	time_t lastcall;                     /*!< When last successful call was hungup */
 	struct call_queue *lastqueue;	     /*!< Last queue we received a call */
+	unsigned int realtime:1;             /*!< Is this member realtime? */
+	unsigned int paused:1;               /*!< Are we paused (not accepting calls)? */
 	unsigned int dead:1;                 /*!< Used to detect members deleted in realtime */
 	unsigned int delme:1;                /*!< Flag to delete entry on reload */
+	unsigned int ignorebusy:1;           /*!< Flag to ignore member if the status is not available */
 	char rt_uniqueid[80];                /*!< Unique id of realtime member entry */
-	unsigned int ignorebusy:1;           /*!< Flag to ignore member if the status is not available */
 	struct mem_state *device;            /*!< Device information */
 };
 
@@ -1320,6 +1320,31 @@
 	}
 }
 
+#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);
+        return q;
+}
+
+static inline struct call_queue *queue_unref(struct call_queue *q)
+{
+        ao2_ref(q, -1);
+        return NULL;
+}
+#endif
+
 /*! \brief Set variables of queue */
 static void set_queue_variables(struct call_queue *q, struct ast_channel *chan)
 {
@@ -1364,7 +1389,7 @@
 	/* 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. */
-	ao2_ref(q, 1);
+	queue_ref(q);
 	new->parent = q;
 	new->pos = ++(*pos);
 	new->opos = *pos;
@@ -1459,13 +1484,13 @@
 	while ((q = ao2_iterator_next(&qiter))) {
 		ao2_lock(q);
 		if (q->maskmemberstatus) {
+			ao2_unlock(q);
 			ao2_ref(q, -1);
-			ao2_unlock(q);
 			continue;
 		}
 		miter = ao2_iterator_init(q->members, 0);
 		while((m = ao2_iterator_next(&miter))) {
-			if (strcmp(s->state_interface, s->state_interface)) {
+			if (strcmp(m->device->state_interface, s->state_interface)) {
 				ao2_ref(m, -1);
 				continue;
 			}
@@ -1487,11 +1512,10 @@
 		}
 		ao2_iterator_destroy(&miter);
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&qiter);
 }
-
 
 /*! \brief callback used when device state changes*/
 static void device_state_cb(const struct ast_event *event, void *unused)
@@ -1508,7 +1532,7 @@
 		return;
 	}
 
-	if ((s = ao2_find(devices, (void *)device, 0))) {
+	if ((s = ao2_find(devices, (char *)device, 0))) {
 		s->status = state;
 		update_status(s);
 		ao2_ref(s, -1);
@@ -1641,19 +1665,19 @@
 		ao2_ref(cur, -1);
 		return NULL;
 	}
-	ast_copy_string(cur->interface, interface, sizeof(cur->interface));
-	if (!strchr(cur->interface, '/')) {
-		ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
-	}
 
 	cur->penalty = penalty;
 	cur->paused = paused;
-
+	ast_copy_string(cur->interface, interface, sizeof(cur->interface));
 	if (!ast_strlen_zero(membername)) {
 		ast_copy_string(cur->membername, membername, sizeof(cur->membername));
 	} else {
 		ast_copy_string(cur->membername, interface, sizeof(cur->membername));
 	}
+	if (!strchr(cur->interface, '/')) {
+		ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
+	}
+
 
 	return cur;
 }
@@ -2249,9 +2273,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);
+			queue_t_unref(q, "String field allocation failed");
 			return NULL;
 		}
 		ast_string_field_set(q, name, queuename);
@@ -2281,12 +2305,12 @@
 	char tmpbuf[64];	/* Must be longer than the longest queue param name. */
 
 	/* Static queues override realtime. */
-	if ((q = ao2_find(queues, (char *)queuename, 0))) {
+	if ((q = ao2_t_find(queues, (char *)queuename, 0, "Check if static queue exists"))) {
 		ao2_lock(q);
 		if (!q->realtime) {
 			if (q->dead) {
 				ao2_unlock(q);
-				ao2_ref(q, -1);
+				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);
@@ -2298,7 +2322,6 @@
 		/* Not found in the list, and it's not realtime ... */
 		return NULL;
 	}
-
 	/* Check if queue is defined in realtime. */
 	if (!queue_vars) {
 		/* Delete queue from in-core list if it has been deleted in realtime. */
@@ -2310,9 +2333,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);
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Queue is dead; can't return it");
 		}
 		return NULL;
 	}
@@ -2323,6 +2346,7 @@
 		if (!(q = alloc_queue(queuename))) {
 			return NULL;
 		}
+		ao2_lock(q);
 		clear_queue(q);
 		q->realtime = 1;
 		q->membercount = 0;
@@ -2344,8 +2368,7 @@
 		if (!tmpvar) {
 			q->strategy = QUEUE_STRATEGY_RINGALL;
 		}
-		ao2_link(queues, q);
-		ao2_lock(q);
+		queues_t_link(queues, q, "Add queue to container");
 	}
 	init_queue(q);		/* Ensure defaults for all parameters not set explicitly. */
 
@@ -2367,7 +2390,7 @@
 		queue_set_param(q, tmp_name, v->value, -1, 0);
 	}
 
-	/* Temporarily set realtime members dead so we can detect deleted ones. 
+	/* Temporarily set realtime members dead so we can detect deleted ones.
 	 * Also set the membercount correctly for realtime*/
 	mem_iter = ao2_iterator_init(q->members, 0);
 	while ((m = ao2_iterator_next(&mem_iter))) {
@@ -2413,7 +2436,7 @@
 	int prev_weight = 0;
 
 	/* Find the queue in the in-core list first. */
-	q = ao2_find(queues, (char *)queuename, 0);
+	q = ao2_t_find(queues, (char *)queuename, 0, "Look for queue in memory first");
 
 	if (!q || q->realtime) {
 		/*! \note Load from realtime before taking the "queues" container lock, to avoid blocking all
@@ -2436,7 +2459,7 @@
 		}
 		if (q) {
 			prev_weight = q->weight ? 1 : 0;
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Need to find realtime queue");
 		}
 
 		q = find_queue_by_name_rt(queuename, queue_vars, member_config);
@@ -2539,7 +2562,7 @@
 		if ((status = get_member_status(q, qe->max_penalty, qe->min_penalty, q->joinempty))) {
 			*reason = QUEUE_JOINEMPTY;
 			ao2_unlock(q);
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Done with realtime queue");
 			return res;
 		}
 	}
@@ -2602,7 +2625,7 @@
 		ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
 	}
 	ao2_unlock(q);
-	ao2_ref(q, -1);
+	queue_t_unref(q, "Done with realtime queue");
 
 	return res;
 }
@@ -2842,7 +2865,7 @@
 	if (!(q = qe->parent)) {
 		return;
 	}
-	ao2_ref(q, 1);
+	queue_t_ref(q, "Copy queue pointer from queue entry");
 	ao2_lock(q);
 
 	prev = NULL;
@@ -2886,10 +2909,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 */
-	ao2_ref(q, -1);
+	queue_t_unref(q, "Expire copied reference");
 }
 
 /*!
@@ -3001,9 +3024,9 @@
 	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 (q == rq) { /* don't check myself, could deadlock */
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Done with iterator");
 			continue;
 		}
 		ao2_lock(q);
@@ -3018,7 +3041,7 @@
 			}
 		}
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator");
 		if (found) {
 			break;
 		}
@@ -4116,7 +4139,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);
@@ -4125,7 +4148,7 @@
 				ao2_ref(mem, -1);
 			}
 			ao2_unlock(qtmp);
-			ao2_ref(qtmp, -1);
+			queue_t_unref(qtmp, "Done with iterator");
 		}
 		ao2_iterator_destroy(&queue_iter);
 	} else {
@@ -4382,7 +4405,7 @@
 	if (ao2_ref(qeb, -1) == 1) {
 		set_queue_variables(q, chan);
 		/* This unrefs the reference we made in try_calling when we allocated qeb */
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Expire bridge_config reference");
 	}
 }
 
@@ -5148,7 +5171,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.
 			 */
-			ao2_ref(qe->parent, 1);
+			queue_t_ref(qe->parent, "For bridge_config reference");
 		}
 
 		time(&callstart);
@@ -5217,11 +5240,7 @@
 
 static struct member *interface_exists(struct call_queue *q, const char *interface)
 {
-	if (q) {
-		return ao2_find(q->members, (char *)interface, 0);
-	} else {
-		return NULL;
-	}
+	return (q) ? ao2_find(q->members, (char *)interface, 0) : NULL;
 }
 
 
@@ -5283,7 +5302,7 @@
 	int res = RES_NOSUCHQUEUE;
 
 	ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
-	if ((q = ao2_find(queues, (char *)queuename, 0))) {
+	if ((q = ao2_t_find(queues, (char *)queuename, 0, "Temporary reference for interface removal"))) {
 		ao2_lock(q);
 		if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
 			/* XXX future changes should beware of this assumption!! */
@@ -5293,7 +5312,7 @@
 			} else if (!mem->dynamic) {
 				ao2_ref(mem, -1);
 				ao2_unlock(q);
-				ao2_ref(q, -1);
+				queue_t_unref(q, "Interface wasn't dynamic, expiring temporary reference");
 				return RES_NOT_DYNAMIC;
 			}
 			q->membercount--;
@@ -5313,7 +5332,7 @@
 			res = RES_EXISTS;
 		}
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Expiring temporary reference");
 	}
 
 	return res;
@@ -5339,7 +5358,7 @@
 	}
 
 	ao2_lock(q);
-	if (!(old_member = interface_exists(q, interface))) {
+	if ((old_member = interface_exists(q, interface)) == NULL) {
 		if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface))) {
 			new_member->dynamic = 1;
 			ao2_link(q->members, new_member);
@@ -5376,7 +5395,7 @@
 		res = RES_EXISTS;
 	}
 	ao2_unlock(q);
-	ao2_ref(q, -1);
+	queue_t_unref(q, "Expiring temporary reference");
 
 	return res;
 }
@@ -5394,26 +5413,26 @@
 		ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
 
 	queue_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&queue_iter))) {
-		if (!ast_strlen_zero(queuename) && (strcasecmp(queuename, q->name))) {
-			ao2_ref(q, -1);
-			continue;
-		}
+	while ((q = ao2_t_iterator_next(&queue_iter, "Iterate over queues"))) {
 		ao2_lock(q);
-		if ((mem = interface_exists(q, interface))) {
-			found = 1;
+		if ((ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) &&
+		    (mem = interface_exists(q, interface))) {
 			if (mem->paused == paused) {
 				ast_debug(1, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
 			}
 
 			if ((mem->realtime) && (update_realtime_member_field(mem, q->name, "paused", paused ? "1" : "0"))) {
 				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++;
 			mem->paused = paused;
 
-			if (queue_persistent_members) {
+			if (queue_persistent_members)
 				dump_queue_members(q);
-			}
 
 			ast_queue_log(q->name, "NONE", mem->membername, (paused ? "PAUSE" : "UNPAUSE"), "%s", S_OR(reason, ""));
 
@@ -5435,11 +5454,15 @@
 			}
 			ao2_ref(mem, -1);
 		}
+
+		if (!ast_strlen_zero(queuename) && !strcasecmp(queuename, q->name)) {
+			ao2_unlock(q);
+			queue_t_unref(q, "Done with iterator");
+			break;
+		}
+
 		ao2_unlock(q);
-		ao2_ref(q, -1);
-		if (!ast_strlen_zero(queuename) && !strcasecmp(queuename, q->name)) {
-			break;
-		}
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -5484,7 +5507,7 @@
 	if (foundinterface) {
 		return RESULT_SUCCESS;
 	} else if (!foundqueue) {
-		ast_log (LOG_ERROR, "Invalid queuename\n");
+		ast_log (LOG_ERROR, "Invalid queuename\n"); 
 	} else {
 		ast_log (LOG_ERROR, "Invalid interface\n");
 	}
@@ -5501,18 +5524,18 @@
 	struct call_queue *q;
 	struct member *mem;
 
-	if ((q = ao2_find(queues, queuename, 0))) {
+	if ((q = ao2_t_find(queues, queuename, 0, "Search for queue"))) {
 		foundqueue = 1;
 		ao2_lock(q);
 		if ((mem = interface_exists(q, interface))) {
 			penalty = mem->penalty;
 			ao2_ref(mem, -1);
 			ao2_unlock(q);
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Search complete");
 			return penalty;
 		}
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Search complete");
 	}
 
 	/* some useful debuging */
@@ -5549,7 +5572,7 @@
 
 		queue_name = entry->key + strlen(pm_family) + 2;
 
-		cur_queue = ao2_find(queues, (char *)queue_name, 0);
+		cur_queue = ao2_t_find(queues, (char *)queue_name, 0, "Reload queue members");
 
 		if (!cur_queue) {
 			cur_queue = load_realtime_queue(queue_name);
@@ -5564,7 +5587,7 @@
 		}
 
 		if (ast_db_get(pm_family, queue_name, queue_data, PM_MAX_LEN)) {
-			ao2_ref(cur_queue, -1);
+			queue_t_unref(cur_queue, "Expire reload reference");
 			continue;
 		}
 
@@ -5606,7 +5629,7 @@
 				break;
 			}
 		}
-		ao2_ref(cur_queue, -1);
+		queue_t_unref(cur_queue, "Expire reload reference");
 	}
 
 	if (db_tree) {
@@ -6185,8 +6208,7 @@
 		/* 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 */
-		ao2_ref(qe.parent, -1);
-		qe.parent = NULL;
+		qe.parent = queue_unref(qe.parent);
 	}
 
 	return res;
@@ -6210,7 +6232,7 @@
 		return -1;
 	}
 
-	if ((q = ao2_find(queues, data, 0))) {
+	if ((q = ao2_t_find(queues, data, 0, "Find for QUEUE() function"))) {
 		ao2_lock(q);
 		if (q->setqueuevar) {
 			sl = 0;
@@ -6228,7 +6250,7 @@
 		}
 
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with QUEUE() function");
 	} else {
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 	}
@@ -6255,7 +6277,7 @@
 	q = load_realtime_queue(data);
 	snprintf(buf, len, "%d", q != NULL? 1 : 0);
 	if (q) {
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with temporary reference in QUEUE_EXISTS()");
 	}
 
 	return 0;
@@ -6340,7 +6362,7 @@
 			ao2_ref(m, -1);
 		}
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER()");
 	} else {
 		ast_log(LOG_WARNING, "queue %s was not found\n", args.queuename);
 	}
@@ -6463,7 +6485,7 @@
 		}
 		ao2_iterator_destroy(&mem_iter);
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with temporary reference in QUEUE_MEMBER_COUNT");
 	} else {
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 	}
@@ -6487,11 +6509,11 @@
 		return -1;
 	}
 
-	if ((q = ao2_find(queues, data, 0))) {
+	if ((q = ao2_t_find(queues, data, 0, "Find for QUEUE_WAITING_COUNT()"))) {
 		ao2_lock(q);
 		count = q->count;
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with reference in 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
@@ -6521,7 +6543,7 @@
 		return -1;
 	}
 
-	if ((q = ao2_find(queues, data, 0))) {
+	if ((q = ao2_t_find(queues, data, 0, "Find for QUEUE_MEMBER_LIST()"))) {
 		int buflen = 0, count = 0;
 		struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
 
@@ -6544,7 +6566,7 @@
 		}
 		ao2_iterator_destroy(&mem_iter);
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with QUEUE_MEMBER_LIST()");
 	} else
 		ast_log(LOG_WARNING, "queue %s was not found\n", data);
 
@@ -6871,7 +6893,7 @@
 	const int member_reload = ast_test_flag(mask, QUEUE_RELOAD_MEMBER);
 	int prev_weight = 0;
 	struct ast_variable *var;
-	if (!(q = ao2_find(queues, (char *)queuename, 0))) {
+		if (!(q = ao2_t_find(queues, (char *)queuename, 0, "Find queue for reload"))) {
 		if (queue_reload) {
 			/* Make one then */
 			if (!(q = alloc_queue(queuename))) {
@@ -6899,7 +6921,7 @@
 			/* It should be impossible to *not* hit this case*/
 			ao2_unlock(q);
 		}
-		ao2_ref(q, -1);
+		queue_t_unref(q, "We exist! Expiring temporary pointer");
 		return;
 	}
 	/* Due to the fact that the "linear" strategy will have a different allocation
@@ -6947,11 +6969,11 @@
 	}
 
 	if (new) {
-		ao2_link(queues, q);
+		queues_t_link(queues, q, "Add queue to container");
 	} else {
 		ao2_unlock(q);
 	}
-	ao2_ref(q, -1);
+	queue_t_unref(q, "Expiring creation reference");
 }
 
 static int mark_dead_and_unfound(void *obj, void *arg, int flags)
@@ -7048,13 +7070,12 @@
 {
 	struct call_queue *q;
 	struct ao2_iterator 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 (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename))
 			clear_queue(q);
-		}
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 	return 0;
@@ -7119,7 +7140,7 @@
 
 	if (argc == 3)	{ /* specific queue */
 		if ((q = load_realtime_queue(argv[2]))) {
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Done with temporary pointer");
 		}
 	} else if (ast_check_realtime("queues")) {
 		/* This block is to find any queues which are defined in realtime but
@@ -7130,7 +7151,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))) {
-					ao2_ref(q, -1);
+					queue_t_unref(q, "Done with temporary pointer");
 				}
 			}
 			ast_config_destroy(cfg);
@@ -7139,7 +7160,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;
 
@@ -7152,15 +7173,15 @@
 			realtime_queue = load_realtime_queue(q->name);
 			if (!realtime_queue) {
 				ao2_unlock(q);
-				ao2_ref(q, -1);
+				queue_t_unref(q, "Done with iterator");
 				continue;
 			}
-			ao2_ref(realtime_queue, -1);
+			queue_t_unref(realtime_queue, "Queue is already in memory");
 		}
 
 		if (argc == 3 && strcasecmp(q->name, argv[2])) {
 			ao2_unlock(q);
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Done with iterator");
 			continue;
 		}
 		found = 1;
@@ -7228,7 +7249,7 @@
 		}
 		do_print(s, fd, "");	/* blank line between entries */
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator"); /* Unref the iterator's reference */
 	}
 	ao2_iterator_destroy(&queue_iter);
 	ao2_unlock(queues);
@@ -7252,13 +7273,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);
-			ao2_ref(q, -1);
+			queue_t_unref(q, "Done with iterator");
 			break;
 		}
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -7357,7 +7378,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 */
@@ -7399,7 +7420,7 @@
 				q->name, qmemcount, qmemavail, qchancount, q->holdtime, q->talktime, qlongestholdtime, idText);
 		}
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 	astman_append(s,
@@ -7432,7 +7453,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 */
@@ -7501,7 +7522,7 @@
 			}
 		}
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -7861,7 +7882,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))) {
@@ -7870,7 +7891,7 @@
 				ao2_unlock(q);
 				tmp = ast_strdup(m->interface);
 				ao2_ref(m, -1);
-				ao2_ref(q, -1);
+				queue_t_unref(q, "Done with iterator, returning interface name");
 				ao2_iterator_destroy(&mem_iter);
 				ao2_iterator_destroy(&queue_iter);
 				return tmp;
@@ -7879,7 +7900,7 @@
 		}
 		ao2_iterator_destroy(&mem_iter);
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Done with iterator");
 	}
 	ao2_iterator_destroy(&queue_iter);
 
@@ -7890,7 +7911,6 @@
 {
 	const char *queuename, *interface;
 	struct member *mem = NULL;
-	int ret = 0;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -7912,40 +7932,36 @@
 	queuename = a->argv[5];
 	interface = a->argv[3];
 
-	if (log_membername_as_agent) {
-		mem = find_member_by_queuename_and_interface(queuename, interface);
-	}
-
 	switch (remove_from_queue(queuename, interface)) {
 	case RES_OKAY:
+		if (log_membername_as_agent) {
+			mem = find_member_by_queuename_and_interface(queuename, interface);
+		}
 		if (!mem || ast_strlen_zero(mem->membername)) {
 			ast_queue_log(queuename, "CLI", interface, "REMOVEMEMBER", "%s", "");
 		} else {
 			ast_queue_log(queuename, "CLI", mem->membername, "REMOVEMEMBER", "%s", "");
 		}
+		if (mem) {
+			ao2_ref(mem, -1);
+		}
 		ast_cli(a->fd, "Removed interface %s from queue '%s'\n", interface, queuename);
-		ret = 1;
+		return CLI_SUCCESS;
 	case RES_EXISTS:
 		ast_cli(a->fd, "Unable to remove interface '%s' from queue '%s': Not there\n", interface, queuename);
-		break;
+		return CLI_FAILURE;
 	case RES_NOSUCHQUEUE:
 		ast_cli(a->fd, "Unable to remove interface from queue '%s': No such queue\n", queuename);
-		break;
+		return CLI_FAILURE;
 	case RES_OUTOFMEMORY:
 		ast_cli(a->fd, "Out of memory\n");
-		break;
+		return CLI_FAILURE;
 	case RES_NOT_DYNAMIC:
 		ast_cli(a->fd, "Unable to remove interface '%s' from queue '%s': Member is not dynamic\n", interface, queuename);
-		break;
+		return CLI_FAILURE;
 	default:
-		break;
-	}
-
-	if (mem) {
-		ao2_ref(mem, -1);
-	}
-
-	return (ret) ? CLI_SUCCESS : CLI_FAILURE;
+		return CLI_FAILURE;
+	}
 }
 
 static char *complete_queue_pause_member(const char *line, const char *word, int pos, int state)
@@ -8483,7 +8499,7 @@
 				!ast_strlen_zero(queuename);
 				queuename = ast_category_browse(cfg, queuename)) {
 			if ((queue = load_realtime_queue(queuename))) {
-				ao2_ref(queue, -1);
+				queue_unref(queue);
 			}
 		}
 		ast_config_destroy(cfg);
@@ -8497,15 +8513,15 @@
 			queue_realtime = load_realtime_queue(queue->name);
 			if (!queue_realtime) {
 				ao2_unlock(queue);
-				ao2_ref(queue, -1);
+				queue_unref(queue);
 				continue;
 			}
-			ao2_ref(queue_realtime, -1);
+			queue_unref(queue_realtime);
 		}
 
 		queues_data_provider_get_helper(search, data_root, queue);
 		ao2_unlock(queue);
-		ao2_ref(queue, -1);
+		queue_unref(queue);
 	}
 	ao2_iterator_destroy(&i);
 
@@ -8526,8 +8542,8 @@
 	int res;
 	struct ast_context *con;
 	struct ao2_iterator q_iter;
+	struct call_queue *q = NULL;
 	struct ao2_iterator d_iter;
-	struct call_queue *q = NULL;
 	struct interface *d = NULL;
 
 	ast_cli_unregister_multiple(cli_queue, ARRAY_LEN(cli_queue));
@@ -8567,9 +8583,9 @@
 	}
 
 	q_iter = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&q_iter))) {
-		ao2_unlink(queues, q);
-		ao2_ref(q, -1);
+	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);
@@ -8669,7 +8685,7 @@
 		ao2_lock(q);
 		mem = ao2_find(q->members, interface, OBJ_KEY);
 		ao2_unlock(q);
-		ao2_ref(q, -1);
+		queue_t_unref(q, "Expiring temporary reference.");
 	}
 	return mem;
 }




More information about the asterisk-commits mailing list