[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