diff options
author | Sean Bright <sean@malleable.com> | 2010-01-11 16:40:23 +0000 |
---|---|---|
committer | Sean Bright <sean@malleable.com> | 2010-01-11 16:40:23 +0000 |
commit | ba6201cae604be1fc5eb270784ffd21a7aa45d07 (patch) | |
tree | f3011a4d5524165c3aebe8ac15b9c42c2eef83d3 /main/astobj2.c | |
parent | 1ad299911278142389f7fe8cc6df006f9e8d3d1c (diff) |
Fix ao2_callback when both OBJ_MULTIPLE and OBJ_NODATA are passed.
There is an issue which only affects trunk and the new ao2_callback OBJ_MULTIPLE
implementation. When both OBJ_MULTIPLE and OBJ_NODATA are passed, only the first
object is visited, regardless of what is returned by the specified callback. This
causes a problem when we are clearing a container, i.e.:
ao2_callback(container, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
Only unlinks the first object. This patch resolves this.
(closes issue #16564)
Reported by: pj
Patches:
issue16564_20100111.diff uploaded by seanbright (license 71)
Tested by: pj, seanbright
Review: https://reviewboard.asterisk.org/r/457/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@239113 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/astobj2.c')
-rw-r--r-- | main/astobj2.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/main/astobj2.c b/main/astobj2.c index a7dd7cc25..5e4cef40a 100644 --- a/main/astobj2.c +++ b/main/astobj2.c @@ -593,6 +593,8 @@ static int cb_true_data(void *user_data, void *arg, void *data, int flags) return CMP_MATCH; } +#define USE_CONTAINER(x) (((x) & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE) + /*! * Browse the container using different stategies accoding the flags. * \return Is a pointer to an object or to a list of object if OBJ_MULTIPLE is @@ -615,7 +617,7 @@ static void *internal_ao2_callback(struct ao2_container *c, if (INTERNAL_OBJ(c) == NULL) /* safety check on the argument */ return NULL; - if ((flags & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE) { + if (USE_CONTAINER(flags)) { /* we need to return an ao2_iterator with the results, * as there could be more than one. the iterator will * hold the only reference to a container that has all the @@ -708,7 +710,7 @@ static void *internal_ao2_callback(struct ao2_container *c, /* if we are in OBJ_MULTIPLE mode, link the object into the * container that will hold the results */ - if (ret && (multi_container != NULL)) { + if (ret && USE_CONTAINER(flags)) { __ao2_link(multi_container, ret); ret = NULL; } @@ -731,9 +733,10 @@ static void *internal_ao2_callback(struct ao2_container *c, ast_free(cur); /* free the link record */ } - if ((match & CMP_STOP) || (multi_container == NULL)) { - /* We found the only match we need */ - i = last; /* force exit from outer loop */ + if ((match & CMP_STOP) || USE_CONTAINER(flags)) { + /* We found our only (or last) match, so force an exit from + the outside loop. */ + i = last; break; } } @@ -750,7 +753,7 @@ static void *internal_ao2_callback(struct ao2_container *c, } } ao2_unlock(c); - if (multi_container != NULL) { + if (USE_CONTAINER(flags)) { *multi_iterator = ao2_iterator_init(multi_container, AO2_ITERATOR_DONTLOCK | AO2_ITERATOR_UNLINK | AO2_ITERATOR_MALLOCD); ao2_ref(multi_container, -1); |