mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 04:11:08 +00:00
fixes astobj2 unlinking of multiple objects when OBJ_MULTIPLE was disabled
When OBJ_MULTIPLE was off but OBJ_UNLINK was on, all the items in a bucket were being unlinked instead of just the first match. This fixes that. Review: https://reviewboard.asterisk.org/r/490/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@245147 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -666,7 +666,8 @@ enum search_flags {
|
|||||||
* its refcount.
|
* its refcount.
|
||||||
*/
|
*/
|
||||||
OBJ_NODATA = (1 << 1),
|
OBJ_NODATA = (1 << 1),
|
||||||
/*! Don't stop at the first match in ao2_callback().
|
/*! Don't stop at the first match in ao2_callback() unless the result of
|
||||||
|
* of the callback function == (CMP_STOP | CMP_MATCH).
|
||||||
*/
|
*/
|
||||||
OBJ_MULTIPLE = (1 << 2),
|
OBJ_MULTIPLE = (1 << 2),
|
||||||
/*! obj is an object of the same type as the one being searched for,
|
/*! obj is an object of the same type as the one being searched for,
|
||||||
|
@@ -593,8 +593,6 @@ static int cb_true_data(void *user_data, void *arg, void *data, int flags)
|
|||||||
return CMP_MATCH;
|
return CMP_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define USE_CONTAINER(x) (((x) & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE)
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Browse the container using different stategies accoding the flags.
|
* 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
|
* \return Is a pointer to an object or to a list of object if OBJ_MULTIPLE is
|
||||||
@@ -617,7 +615,12 @@ static void *internal_ao2_callback(struct ao2_container *c,
|
|||||||
if (INTERNAL_OBJ(c) == NULL) /* safety check on the argument */
|
if (INTERNAL_OBJ(c) == NULL) /* safety check on the argument */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (USE_CONTAINER(flags)) {
|
/*
|
||||||
|
* This logic is used so we can support OBJ_MULTIPLE with OBJ_NODATA
|
||||||
|
* turned off. This if statement checks for the special condition
|
||||||
|
* where multiple items may need to be returned.
|
||||||
|
*/
|
||||||
|
if ((flags & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE) {
|
||||||
/* we need to return an ao2_iterator with the results,
|
/* we need to return an ao2_iterator with the results,
|
||||||
* as there could be more than one. the iterator will
|
* as there could be more than one. the iterator will
|
||||||
* hold the only reference to a container that has all the
|
* hold the only reference to a container that has all the
|
||||||
@@ -707,10 +710,10 @@ static void *internal_ao2_callback(struct ao2_container *c,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we are in OBJ_MULTIPLE mode, link the object into the
|
/* If we are in OBJ_MULTIPLE mode and OBJ_NODATE is off,
|
||||||
* container that will hold the results
|
* link the object into the container that will hold the results.
|
||||||
*/
|
*/
|
||||||
if (ret && USE_CONTAINER(flags)) {
|
if (ret && (multi_container != NULL)) {
|
||||||
__ao2_link(multi_container, ret);
|
__ao2_link(multi_container, ret);
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
}
|
}
|
||||||
@@ -733,7 +736,7 @@ static void *internal_ao2_callback(struct ao2_container *c,
|
|||||||
ast_free(cur); /* free the link record */
|
ast_free(cur); /* free the link record */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((match & CMP_STOP) || USE_CONTAINER(flags)) {
|
if ((match & CMP_STOP) || !(flags & OBJ_MULTIPLE)) {
|
||||||
/* We found our only (or last) match, so force an exit from
|
/* We found our only (or last) match, so force an exit from
|
||||||
the outside loop. */
|
the outside loop. */
|
||||||
i = last;
|
i = last;
|
||||||
@@ -753,7 +756,9 @@ static void *internal_ao2_callback(struct ao2_container *c,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ao2_unlock(c);
|
ao2_unlock(c);
|
||||||
if (USE_CONTAINER(flags)) {
|
|
||||||
|
/* if multi_container was created, we are returning multiple objects */
|
||||||
|
if (multi_container != NULL) {
|
||||||
*multi_iterator = ao2_iterator_init(multi_container,
|
*multi_iterator = ao2_iterator_init(multi_container,
|
||||||
AO2_ITERATOR_DONTLOCK | AO2_ITERATOR_UNLINK | AO2_ITERATOR_MALLOCD);
|
AO2_ITERATOR_DONTLOCK | AO2_ITERATOR_UNLINK | AO2_ITERATOR_MALLOCD);
|
||||||
ao2_ref(multi_container, -1);
|
ao2_ref(multi_container, -1);
|
||||||
|
Reference in New Issue
Block a user