[asterisk-commits] mmichelson: branch mmichelson/queue_refcount r81457 - /team/mmichelson/queue_...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Sep 4 17:11:05 CDT 2007
Author: mmichelson
Date: Tue Sep 4 17:11:05 2007
New Revision: 81457
URL: http://svn.digium.com/view/asterisk?view=rev&rev=81457
Log:
More changes. Consider this the first draft of refcounted members.
**NOTE: COMPLETELY UNTESTED! PROBABLY BROKEN!**
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=81457&r1=81456&r2=81457
==============================================================================
--- team/mmichelson/queue_refcount/apps/app_queue.c (original)
+++ team/mmichelson/queue_refcount/apps/app_queue.c Tue Sep 4 17:11:05 2007
@@ -535,7 +535,7 @@
break;
default:
ast_mutex_unlock(&q->lock);
- ao2_unref(member);
+ ao2_ref(member, -1);
return QUEUE_NORMAL;
}
}
@@ -1131,6 +1131,7 @@
while ((m = ao2_iterator_next(&mem_iter))) {
if (m->realtime)
m->dead = 1;
+ ao2_ref(m, -1);
}
while ((interface = ast_category_browse(member_config, interface))) {
@@ -1144,11 +1145,6 @@
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);
@@ -1205,6 +1201,7 @@
while ((m = ao2_iterator_next(&mem_iter))) {
if (m->realtime)
m->dead = 1;
+ ao2_ref(m, -1);
}
while ((interface = ast_category_browse(member_config, interface))) {
@@ -1561,6 +1558,7 @@
ast_hangup(outgoing->chan);
oo = outgoing;
outgoing = outgoing->q_next;
+ ao2_ref(oo->member, -1);
free(oo);
}
}
@@ -2428,6 +2426,7 @@
char vars[2048];
int forwardsallowed = 1;
int callcompletedinsl;
+ struct ao2_iterator mem_iter;
memset(&bridge_config, 0, sizeof(bridge_config));
time(&now);
@@ -2481,13 +2480,15 @@
if (!ast_strlen_zero(announceoverride))
announce = announceoverride;
- for (; cur; cur = cur->next) {
+ mem_iter = ao2_iterator_init(qe->parent->members);
+ while ((cur = ao2_iterator_next(&mem_iter))) {
struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
if (!tmp) {
ast_mutex_unlock(&qe->parent->lock);
if (use_weight)
ao2_unlock(queues);
+ ao2_ref(cur, -1);
goto out;
}
tmp->stillgoing = -1;
@@ -2507,8 +2508,12 @@
if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
break;
} else {
+ ao2_ref(cur, -1);
free(tmp);
}
+ /*Note: We do NOT decrease the reference count of the members here as we typically would while iterating
+ * We want these references to persist until we have finished using the call_attempts
+ */
}
if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
to = (qe->expire - now) * 1000;
@@ -2552,6 +2557,7 @@
callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
ast_mutex_unlock(&qe->parent->lock);
member = lpeer->member;
+ ao2_ref(member, 1);
hangupcalls(outgoing, peer);
outgoing = NULL;
if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
@@ -2606,6 +2612,7 @@
ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
record_abandoned(qe);
ast_hangup(peer);
+ ao2_ref(member, -1);
return -1;
}
}
@@ -2621,6 +2628,7 @@
ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
record_abandoned(qe);
ast_hangup(peer);
+ ao2_ref(member, -1);
return -1;
}
/* Begin Monitoring */
@@ -2820,17 +2828,14 @@
static struct member *interface_exists(struct call_queue *q, const char *interface)
{
- struct member *mem;
+ struct member tmpmem;
if (!q)
return NULL;
- for (mem = q->members; mem; mem = mem->next) {
- if (!strcasecmp(interface, mem->interface))
- return mem;
- }
-
- return NULL;
+ ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
+ /*XXX This is probably not what I want, but I need to double check*/
+ return ao2_find(q->members, &tmpmem, OBJ_NODATA);
}
@@ -2845,13 +2850,15 @@
char value[PM_MAX_LEN];
int value_len = 0;
int res;
+ struct ao2_iterator mem_iter;
memset(value, 0, sizeof(value));
if (!pm_queue)
return;
- for (cur_member = pm_queue->members; cur_member; cur_member = cur_member->next) {
+ mem_iter = ao2_iterator_init(pm_queue->members, 0);
+ while ((cur_member = ao2_iterator_next(&mem_iter))) {
if (!cur_member->dynamic)
continue;
@@ -2860,9 +2867,11 @@
cur_member->next ? "|" : "");
if (res != strlen(value + value_len)) {
ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
+ ao2_ref(cur_member, -1);
break;
}
value_len += res;
+ ao2_ref(cur_member, -1);
}
if (value_len && !cur_member) {
@@ -2885,6 +2894,7 @@
q = ao2_find(queues, &tmpq, OBJ_POINTER);
ast_mutex_lock(&q->lock);
+ /*XXX WTF? This is so weird...Come back later*/
if ((last_member = interface_exists(q, interface))) {
if ((look = q->members) == last_member) {
q->members = last_member->next;
@@ -3717,6 +3727,7 @@
struct call_queue *q;
struct call_queue tmpq;
struct member *m;
+ struct ao2_iterator mem_iter;
/* Ensure an otherwise empty list doesn't return garbage */
buf[0] = '\0';
@@ -3729,12 +3740,11 @@
ast_copy_string(tmpq.name, data, sizeof(tmpq.name));
u = ast_module_user_add(chan);
- q = ao2_find(queues, &tmpq, OBJ_POINTER);
-
- if (q) {
+ if((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
int buflen = 0, count = 0;
- for (m = q->members; m; m = m->next) {
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((m = ao2_iterator_next(&mem_iter))) {
/* strcat() is always faster than printf() */
if (count++) {
strncat(buf + buflen, ",", len - buflen - 1);
@@ -3745,8 +3755,10 @@
/* Safeguard against overflow (negative length) */
if (buflen >= len - 2) {
ast_log(LOG_WARNING, "Truncating list\n");
+ ao2_ref(m, -1);
break;
}
+ ao2_ref(m, -1);
}
ast_mutex_unlock(&q->lock);
queue_unref(q);
@@ -3804,14 +3816,14 @@
struct ast_config *cfg;
char *cat, *tmp;
struct ast_variable *var;
- struct member *prev, *cur, *newm, *next;
+ struct member *prev, *cur, *newm, *next, tmpmem;
int new;
const char *general_val = NULL;
char parse[80];
char *interface;
char *membername;
int penalty;
- struct ao2_iterator i;
+ struct ao2_iterator queue_iter, mem_iter;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(interface);
AST_APP_ARG(penalty);
@@ -3823,9 +3835,9 @@
return 0;
}
use_weight=0;
- i = ao2_iterator_init(queues, 0);
+ queue_iter = ao2_iterator_init(queues, 0);
/*Mark all non-realtime queues dead for now*/
- while((q = ao2_iterator_next(&i))) {
+ while((q = ao2_iterator_next(&queue_iter))) {
if(!q->realtime)
q->dead = 1;
queue_unref(q);
@@ -3864,10 +3876,12 @@
/* Re-initialize the queue, and clear statistics */
init_queue(q);
clear_queue(q);
- for (cur = q->members; cur; cur = cur->next) {
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((cur = ao2_iterator_next(&mem_iter))) {
if (!cur->dynamic) {
cur->delme = 1;
}
+ ao2_ref(cur, -1);
}
for (var = ast_variable_browse(cfg, cat); var; var = var->next) {
if (!strcasecmp(var->name, "member")) {
@@ -3894,28 +3908,19 @@
membername = interface;
/* Find the old position in the list */
- for (prev = NULL, cur = q->members; cur; prev = cur, cur = cur->next) {
- if (!strcmp(cur->interface, interface)) {
- break;
- }
- }
+ ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
+ cur = ao2_find(q->members, &tmpmem, OBJ_POINTER);
newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0);
if (cur) {
- /* Delete it now */
- newm->next = cur->next;
- if (prev) {
- prev->next = newm;
- } else {
- q->members = newm;
- }
- free(cur);
+ ao2_unlink(q->members, cur);
+ ao2_link(q->members, newm);
+ ao2_ref(cur, -1);
} else {
/* Add them to the master int list if necessary */
add_to_interfaces(interface);
- newm->next = q->members;
- q->members = newm;
+ ao2_link(q->members, newm);
}
q->membercount++;
} else {
@@ -3924,23 +3929,18 @@
}
/* Free remaining members marked as delme */
- for (prev = NULL, cur = q->members;
- cur;
- cur = next) {
- next = cur->next;
-
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((cur = ao2_iterator_next(&mem_iter))) {
if (!cur->delme) {
prev = cur;
continue;
}
-
- if (prev)
- prev->next = next;
- else
- q->members = next;
+ ao2_unlink(q->members, cur);
remove_from_interfaces(cur->interface);
q->membercount--;
- free(cur);
+ /*We decrease count by 2 since we are removing the iterator's reference
+ * plus the container's reference*/
+ ao2_ref(cur, -2);
}
if (q->strategy == QUEUE_STRATEGY_ROUNDROBIN)
@@ -3956,16 +3956,18 @@
}
}
ast_config_destroy(cfg);
- 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->dead) {
ao2_unlink(queues, q);
} else {
ast_mutex_lock(&q->lock);
- for (cur = q->members; cur; cur = cur->next) {
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((cur = ao2_iterator_next(&mem_iter))) {
if(cur->dynamic)
q->membercount++;
cur->status = ast_device_state(cur->interface);
+ ao2_ref(cur, -1);
}
ast_mutex_unlock(&q->lock);
}
@@ -3983,6 +3985,7 @@
time_t now;
struct queue_ent *qe;
struct member *mem;
+ struct ao2_iterator mem_iter;
int pos;
max_buf[0] = '\0';
@@ -4007,7 +4010,8 @@
astman_append(s, " Members: %s", term);
else
ast_cli(fd, " Members: %s", term);
- for (mem = q->members; mem; mem = mem->next) {
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while ((mem = ao2_iterator_next(&mem_iter))) {
max_buf[0] = '\0';
max = max_buf;
max_left = sizeof(max_buf);
@@ -4027,6 +4031,7 @@
astman_append(s, " %s%s%s", mem->interface, max_buf, term);
else
ast_cli(fd, " %s%s%s", mem->interface, max_buf, term);
+ ao2_ref(mem, -1);
}
} else if (s)
astman_append(s, " No Members%s", term);
@@ -4168,15 +4173,15 @@
struct queue_ent *qe;
float sl = 0;
struct member *mem;
- struct ao2_iterator i;
+ struct ao2_iterator queue_iter, mem_iter;
astman_send_ack(s, m, "Queue status will follow");
time(&now);
if (!ast_strlen_zero(id))
snprintf(idText, sizeof(idText), "ActionID: %s\r\n", id);
- 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);
/* List queue properties */
@@ -4197,7 +4202,9 @@
q->name, q->maxlen, q->count, q->holdtime, q->callscompleted,
q->callsabandoned, q->servicelevel, sl, q->weight, idText);
/* List Queue Members */
- for (mem = q->members; mem; mem = mem->next) {
+
+ mem_iter = ao2_iterator_init(q->members, 0);
+ while((mem = ao2_iterator_next(&mem_iter))) {
if (ast_strlen_zero(memberfilter) || !strcmp(mem->interface, memberfilter)) {
astman_append(s, "Event: QueueMember\r\n"
"Queue: %s\r\n"
@@ -4213,6 +4220,7 @@
q->name, mem->interface, mem->dynamic ? "dynamic" : "static",
mem->penalty, mem->calls, (int)mem->lastcall, mem->status, mem->paused, idText);
}
+ ao2_ref(mem, -1);
}
/* List Queue Entries */
pos = 1;
More information about the asterisk-commits
mailing list