Merge code associated with AST-2009-006

(closes issue #12912)
Reported by: rathaus
Tested by: tilghman, russell, dvossel, dbrooks



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@216000 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
David Vossel
2009-09-03 18:32:32 +00:00
parent 82b1e162e1
commit ed1951d895
9 changed files with 1321 additions and 139 deletions

View File

@@ -453,7 +453,7 @@ void *ao2_callback(struct ao2_container *c,
const enum search_flags flags,
ao2_callback_fn cb_fn, void *arg)
{
int i, last; /* search boundaries */
int i, start, last; /* search boundaries */
void *ret = NULL;
if (INTERNAL_OBJ(c) == NULL) /* safety check on the argument */
@@ -483,13 +483,15 @@ void *ao2_callback(struct ao2_container *c,
* (this only for the time being. We need to optimize this.)
*/
if ((flags & OBJ_POINTER)) /* we know hash can handle this case */
i = c->hash_fn(arg, flags & OBJ_POINTER) % c->n_buckets;
start = i = c->hash_fn(arg, flags & OBJ_POINTER) % c->n_buckets;
else /* don't know, let's scan all buckets */
i = -1; /* XXX this must be fixed later. */
/* determine the search boundaries: i..last-1 */
if (i < 0) {
i = 0;
start = i = 0;
last = c->n_buckets;
} else if ((flags & OBJ_CONTINUE)) {
last = c->n_buckets;
} else {
last = i + 1;
@@ -545,6 +547,17 @@ void *ao2_callback(struct ao2_container *c,
}
}
AST_LIST_TRAVERSE_SAFE_END
if (ret) {
/* This assumes OBJ_MULTIPLE with !OBJ_NODATA is still not implemented */
break;
}
if (i == c->n_buckets - 1 && (flags & OBJ_POINTER) && (flags & OBJ_CONTINUE)) {
/* Move to the beginning to ensure we check every bucket */
i = -1;
last = start;
}
}
ao2_unlock(c);
return ret;