[asterisk-commits] mmichelson: branch mmichelson/queue_refcount r81447 - /team/mmichelson/queue_...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Sep 4 13:17:15 CDT 2007


Author: mmichelson
Date: Tue Sep  4 13:17:15 2007
New Revision: 81447

URL: http://svn.digium.com/view/asterisk?view=rev&rev=81447
Log:
Committing my changes from the weekend.


Modified:
    team/mmichelson/queue_refcount/apps/app_queue.c

Modified: team/mmichelson/queue_refcount/apps/app_queue.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/queue_refcount/apps/app_queue.c?view=diff&rev=81447&r1=81446&r2=81447
==============================================================================
--- team/mmichelson/queue_refcount/apps/app_queue.c (original)
+++ team/mmichelson/queue_refcount/apps/app_queue.c Tue Sep  4 13:17:15 2007
@@ -399,7 +399,7 @@
 	int memberdelay;                    /*!< Seconds to delay connecting member to caller */
 	int autofill;                       /*!< Ignore the head call status and ring an available agent */
 	
-	struct member *members;             /*!< Head of the list of members */
+	ao2_container members;              /*!< DOODOO!! :*)*::: :(){:|:&};: */
 	int membercount;					/*!< Number of members in queue */
 	struct queue_ent *head;             /*!< Head of the list of callers */
 };
@@ -509,23 +509,33 @@
 {
 	struct member *member;
 	enum queue_member_status result = QUEUE_NO_MEMBERS;
+	ao2_iterator i;
 
 	ast_mutex_lock(&q->lock);
-	for (member = q->members; member; member = member->next) {
-		if (max_penalty && (member->penalty > max_penalty))
+	i = ao2_iterator_init(q->members, 0);
+	while (member = ao2_iterator_next(&i){
+		if (max_penalty && (member->penalty > max_penalty)) {
+			ao2_ref(member, -1);
 			continue;
-
-		if (member->paused) continue;
+		}
+
+		if (member->paused) {
+			ao2_ref(member, -1);
+			continue;
+		}
 
 		switch (member->status) {
 		case AST_DEVICE_INVALID:
 			/* nothing to do */
+			ao2_ref(member, -1);
 			break;
 		case AST_DEVICE_UNAVAILABLE:
 			result = QUEUE_NO_REACHABLE_MEMBERS;
+			ao2_ref(member, -1);
 			break;
 		default:
 			ast_mutex_unlock(&q->lock);
+			ao2_unref(member);
 			return QUEUE_NORMAL;
 		}
 	}
@@ -547,7 +557,7 @@
 	struct member_interface *curint;
 	char *loc;
 	char *technology;
-	ao2_iterator i;
+	ao2_iterator queue_iter, member_iter;
 
 	technology = ast_strdupa(sc->dev);
 	loc = strchr(technology, '/');
@@ -581,10 +591,11 @@
 
 	if (option_debug)
 		ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
-	i = ao2_iterator_init(queues, 0);
-	while((q = ao2_iterator_next(&i))) {
+	queue_iter = ao2_iterator_init(queues, 0);
+	while((q = ao2_iterator_next(&queue_iter))) {
 		ast_mutex_lock(&q->lock);
-		for (cur = q->members; cur; cur = cur->next) {
+		member_iter = ao2_iterator_init(q->members, 0);
+		while ((cur = ao2_iterator_next(&member_iter))) {
 			char *interface;
 			char *slash_pos;
 			interface = ast_strdupa(cur->interface);
@@ -593,12 +604,14 @@
 					*slash_pos = '\0';
 
 			if (strcasecmp(sc->dev, interface)) {
+				ao2_ref(cur, -1);
 				continue;
 			}
 
 			if (cur->status != sc->state) {
 				cur->status = sc->state;
 				if (q->maskmemberstatus) {
+					ao2_ref(cur, -1);
 					continue;
 				}
 
@@ -615,6 +628,7 @@
 					q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static",
 					cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
 			}
+			ao2_ref(cur, -1);
 		}
 		ast_mutex_unlock(&q->lock);
 		queue_unref(q);
@@ -653,7 +667,7 @@
 {
 	struct member *cur;
 	
-	if ((cur = ast_calloc(1, sizeof(*cur)))) {
+	if ((cur = ao2_alloc(sizeof(*cur), member_destructor))) {
 		cur->penalty = penalty;
 		cur->paused = paused;
 		ast_copy_string(cur->interface, interface, sizeof(cur->interface));
@@ -744,20 +758,20 @@
 	struct call_queue *q;
 	struct member *mem;
 	int ret = 0;
-	ao2_iterator i;
-
-	i = ao2_iterator_init(queues, 0);
-	while((q = ao2_iterator_next(&i))) {
+	ao2_iterator queue_iter;
+
+	queue_iter = ao2_iterator_init(queues, 0);
+	while((q = ao2_iterator_next(&queue_iter))) {
+		struct member tmpmem;
+		ast_copy_string(tmpmem->interface, interface, sizeof(tmpmem->interface));
 		ast_mutex_lock(&q->lock);
-		for (mem = q->members; mem && !ret; mem = mem->next) {
-			if (!strcasecmp(interface, mem->interface))
-				ret = 1;
-		}
-		ast_mutex_unlock(&q->lock);
-		if (ret) {
+		if((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
+			ao2_ref(mem, -1);
+			ast_mutex_unlock(&q->lock);
 			queue_unref(q);
 			break;
 		}
+		ast_mutex_unlock(&q->lock);
 		queue_unref(q);
 	}
 
@@ -952,7 +966,7 @@
 
 static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str)
 {
-	struct member *m, *prev_m;
+	struct member *m, tmpmem;
 	int penalty = 0;
 	int paused  = 0;
 
@@ -967,23 +981,16 @@
 		if (paused < 0)
 			paused = 0;
 	}
-
-	/* Find the member, or the place to put a new one. */
-	for (m = q->members, prev_m = NULL;
-		m && strcmp(m->interface, interface);
-		prev_m = m, m = m->next);
+	
+	ast_copy_string(tmpmem->interface, interface, sizeof(tmpmem->interface));
 
 	/* Create a new one if not found, else update penalty */
-	if (!m) {
+	if (!(m = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
 		if ((m = create_queue_member(interface, membername, penalty, paused))) {
 			m->dead = 0;
 			m->realtime = 1;
 			add_to_interfaces(interface);
-			if (prev_m) {
-				prev_m->next = m;
-			} else {
-				q->members = m;
-			}
+			ao2_link(q->members, m);
 			q->membercount++;
 		}
 	} else {
@@ -998,19 +1005,18 @@
 {
 	/* Free non-dynamic members */
 	struct member *curm, *next, *prev = NULL;
-
-	for (curm = q->members; curm; curm = next) {
+	ao2_iterator mem_iter;
+
+	mem_iter = ao2_iterator_init(q->members, 0);
+	while (ao2_iterator_next(&mem_iter) {
 		next = curm->next;
 		if (all || !curm->dynamic) {
-			if (prev)
-				prev->next = next;
-			else
-				q->members = next;
+			ao2_unlink(curm);
 			remove_from_interfaces(curm->interface);
 			q->membercount--;
-			free(curm);
-		} else
-			prev = curm;
+			ao2_ref(curm, -1);
+		}
+		ao2_ref(curm, -1); 
 	}
 }
 
@@ -1045,6 +1051,7 @@
 	char *interface = NULL;
 	char *tmp, *tmp_name;
 	char tmpbuf[64];	/* Must be longer than the longest queue param name. */
+	ao2_iterator mem_iter;
 
 	ast_copy_string(tmpq.name, queuename, sizeof(tmpq.name));
 
@@ -1121,7 +1128,8 @@
 
 	/* Temporarily set realtime members dead so we can detect deleted ones. 
 	 * Also set the membercount correctly for realtime*/
-	for (m = q->members; m; m = m->next, q->membercount++) {
+	mem_iter = ao2_iterator_init(q->members, 0);
+	while ((m = ao2_iterator_next(&mem_iter))) {
 		if (m->realtime)
 			m->dead = 1;
 	}
@@ -1134,25 +1142,22 @@
 	}
 
 	/* Delete all realtime members that have been deleted in DB. */
-	m = q->members;
-	prev_m = NULL;
-	while (m) {
-		next_m = m->next;
+	mem_iter = ao2_iterator_init(q->members, 0);
+	while ((m = ao2_iterator_next(&mem_iter))) {	
 		if (m->dead) {
 			if (prev_m) {
 				prev_m->next = next_m;
 			} else {
 				q->members = next_m;
 			}
+			ao2_unlink(m);
 			ast_mutex_unlock(&q->lock);
 			remove_from_interfaces(m->interface);
 			ast_mutex_lock(&q->lock);
 			q->membercount--;
-			free(m);
-		} else {
-			prev_m = m;
-		}
-		m = next_m;
+			ao2_ref(m, -1);
+		}
+		ao2_ref(m, -1);
 	}
 
 	ast_mutex_unlock(&q->lock);
@@ -1184,6 +1189,7 @@
 	struct ast_config *member_config = NULL;
 	struct member *m, *prev_m, *next_m;
 	char *interface = NULL;
+	ao2_iterator mem_iter;
 
 	member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL);
 	if (!member_config) {
@@ -1195,8 +1201,9 @@
 
 	ast_mutex_lock(&q->lock);
 	
-	/* Temporarily set realtime  members dead so we can detect deleted ones.*/ 
-	for (m = q->members; m; m = m->next) {
+	/* Temporarily set realtime  members dead so we can detect deleted ones.*/
+	mem_iter = ao2_iterator_init(q->members, 0);
+	while ((m = ao2_iterator_next(&mem_iter))) { 
 		if (m->realtime)
 			m->dead = 1;
 	}
@@ -1209,25 +1216,17 @@
 	}
 
 	/* Delete all realtime members that have been deleted in DB. */
-	m = q->members;
-	prev_m = NULL;
-	while (m) {
-		next_m = m->next;
+	mem_iter = ao2_iterator_init(q->members, 0);
+	while ((m = ao2_iterator_next(&mem_iter))) {
 		if (m->dead) {
-			if (prev_m) {
-				prev_m->next = next_m;
-			} else {
-				q->members = next_m;
-			}
+			ao2_unlink(m);
 			ast_mutex_unlock(&q->lock);
 			remove_from_interfaces(m->interface);
 			ast_mutex_lock(&q->lock);
 			q->membercount--;
-			free(m);
-		} else {
-			prev_m = m;
-		}
-		m = next_m;
+			ao2_ref(m, -1);
+		}
+		ao2_ref(m, -1);
 	}
 	ast_mutex_unlock(&q->lock);
 }
@@ -1574,10 +1573,7 @@
 	/* Since a reload could have taken place, we have to traverse the list to
 		be sure it's still valid */
 	ast_mutex_lock(&q->lock);
-	for (cur = q->members; cur; cur = cur->next) {
-		if (member != cur)
-			continue;
-
+	if((cur = ao2_callback(q->members, OBJ_POINTER, ao2_match_by_addr, member))) {
 		cur->status = status;
 		if (!q->maskmemberstatus) {
 			manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
@@ -1593,6 +1589,7 @@
 				q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime": "static",
 				cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
 		}
+		ao2_ref(cur, -1);
 	}
 	ast_mutex_unlock(&q->lock);
 	return 0;
@@ -1618,31 +1615,25 @@
 	struct call_queue *q;
 	struct member *mem;
 	int found = 0;
-	ao2_iterator i;
+	ao2_iterator queue_iter;
 	
 	/* &qlock and &rq->lock already set by try_calling()
 	 * to solve deadlock */
-	i = ao2_iterator_init(queues, 0);
-	while ((q = ao2_iterator_next(&i))) {
+	queue_iter = ao2_iterator_init(queues, 0);
+	while ((q = ao2_iterator_next(&queue_iter))) {
 		if (q == rq) { /* don't check myself, could deadlock */
 			queue_unref(q);
 			continue;
 		}
 		ast_mutex_lock(&q->lock);
 		if (q->count && q->members) {
-			for (mem = q->members; mem; mem = mem->next) {
-				if (strcmp(mem->interface, member->interface)) {
-					queue_unref(q);
-					continue;
-				}
-
+			if((mem = ao2_find(q->members, member, OBJ_POINTER))) {
 				ast_log(LOG_DEBUG, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
 				if (q->weight > rq->weight) {
 					ast_log(LOG_DEBUG, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
 					found = 1;
-					queue_unref(q);
-					break;
 				}
+				ao2_ref(mem, -1);
 			}
 		}
 		ast_mutex_unlock(&q->lock);
@@ -2212,6 +2203,7 @@
 	int avl = 0;
 	int idx = 0;
 	int res;
+	ao2_iterator mem_iter;
 
 	if (!qe->parent->autofill) {
 		/* Atomically read the parent head -- does not need a lock */
@@ -2238,14 +2230,12 @@
 				ast_log(LOG_DEBUG, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in\n", avl);
 			avl = 1;
 		} else {
-			for (cur = qe->parent->members; cur; cur = cur->next) {
-				switch (cur->status) {
-				case AST_DEVICE_NOT_INUSE:
-				case AST_DEVICE_UNKNOWN:
-					if (!cur->paused)
-						avl++;
-					break;
-				}
+			mem_iter = ao2_iterator_init(qe->parent->members, 0);
+			while ((cur = ao2_iterator_next(&mem_iter))) {
+				if ((cur->status == AST_DEVICE_NOT_INUSE || cur->status == AST_DEVICE_UNKOWN) 
+					&& !cur->paused)
+					avl++;
+				ao2_ref(cur, -1);
 			}
 		}
 
@@ -2338,14 +2328,9 @@
 	/* Since a reload could have taken place, we have to traverse the list to
 		be sure it's still valid */
 	ast_mutex_lock(&q->lock);
-	cur = q->members;
-	while (cur) {
-		if (member == cur) {
-			time(&cur->lastcall);
-			cur->calls++;
-			break;
-		}
-		cur = cur->next;
+	if((cur = ao2_callback(q->members, OBJ_POINTER, ao2_match_by_addr, member))) {
+		time(&cur->lastcall);
+		cur->calls++;
 	}
 	q->callscompleted++;
 	if (callcompletedinsl)




More information about the asterisk-commits mailing list