mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-01 19:43:03 +00:00
Misc changes to make astobj2 enhancement diffs easier to follow.
* Rename astobj2 API parameter funcname to func. * Rename astobj2 API iterator parameter to iter. * Update some documentation for OBJ_MULTIPLE. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@360827 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -462,7 +462,7 @@ enum ao2_alloc_opts {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag,
|
void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag,
|
||||||
const char *file, int line, const char *funcname, int ref_debug);
|
const char *file, int line, const char *func, int ref_debug);
|
||||||
void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options);
|
void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options);
|
||||||
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
@@ -503,7 +503,7 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int __ao2_ref_debug(void *o, int delta, const char *tag, const char *file, int line, const char *funcname);
|
int __ao2_ref_debug(void *o, int delta, const char *tag, const char *file, int line, const char *func);
|
||||||
int __ao2_ref(void *o, int delta);
|
int __ao2_ref(void *o, int delta);
|
||||||
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
@@ -817,8 +817,8 @@ typedef int (ao2_callback_fn)(void *obj, void *arg, int flags);
|
|||||||
*/
|
*/
|
||||||
typedef int (ao2_callback_data_fn)(void *obj, void *arg, void *data, int flags);
|
typedef int (ao2_callback_data_fn)(void *obj, void *arg, void *data, int flags);
|
||||||
|
|
||||||
/*! \brief a very common callback is one that matches by address. */
|
/*! \brief A common ao2_callback is one that matches by address. */
|
||||||
ao2_callback_fn ao2_match_by_addr;
|
int ao2_match_by_addr(void *obj, void *arg, int flags);
|
||||||
|
|
||||||
/*! \brief
|
/*! \brief
|
||||||
* A callback function will return a combination of CMP_MATCH and CMP_STOP.
|
* A callback function will return a combination of CMP_MATCH and CMP_STOP.
|
||||||
@@ -833,22 +833,28 @@ enum _cb_results {
|
|||||||
* Flags passed to ao2_callback() and ao2_hash_fn() to modify its behaviour.
|
* Flags passed to ao2_callback() and ao2_hash_fn() to modify its behaviour.
|
||||||
*/
|
*/
|
||||||
enum search_flags {
|
enum search_flags {
|
||||||
/*! Unlink the object for which the callback function
|
/*!
|
||||||
* returned CMP_MATCH.
|
* Unlink the object for which the callback function returned
|
||||||
|
* CMP_MATCH.
|
||||||
*/
|
*/
|
||||||
OBJ_UNLINK = (1 << 0),
|
OBJ_UNLINK = (1 << 0),
|
||||||
/*! On match, don't return the object hence do not increase
|
/*!
|
||||||
* its refcount.
|
* On match, don't return the object hence do not increase its
|
||||||
|
* refcount.
|
||||||
*/
|
*/
|
||||||
OBJ_NODATA = (1 << 1),
|
OBJ_NODATA = (1 << 1),
|
||||||
/*! Don't stop at the first match in ao2_callback() unless the result of
|
/*!
|
||||||
* of the callback function == (CMP_STOP | CMP_MATCH).
|
* Don't stop at the first match in ao2_callback() unless the
|
||||||
|
* result of of the callback function has the CMP_STOP bit set.
|
||||||
*/
|
*/
|
||||||
OBJ_MULTIPLE = (1 << 2),
|
OBJ_MULTIPLE = (1 << 2),
|
||||||
/*! obj is an object of the same type as the one being searched for,
|
/*!
|
||||||
* so use the object's hash function for optimized searching.
|
* The given obj is an object of the same type as the one being
|
||||||
* The search function is unaffected (i.e. use the one passed as
|
* searched for, so use the object's hash function for optimized
|
||||||
* argument, or match_by_addr if none specified).
|
* searching.
|
||||||
|
*
|
||||||
|
* The matching function is unaffected (i.e. The cb_fn argument
|
||||||
|
* to ao2_callback).
|
||||||
*/
|
*/
|
||||||
OBJ_POINTER = (1 << 3),
|
OBJ_POINTER = (1 << 3),
|
||||||
/*!
|
/*!
|
||||||
@@ -893,7 +899,7 @@ enum search_flags {
|
|||||||
* flags is ignored at the moment. Eventually, it will include the
|
* flags is ignored at the moment. Eventually, it will include the
|
||||||
* value of OBJ_POINTER passed to ao2_callback().
|
* value of OBJ_POINTER passed to ao2_callback().
|
||||||
*/
|
*/
|
||||||
typedef int (ao2_hash_fn)(const void *obj, const int flags);
|
typedef int (ao2_hash_fn)(const void *obj, int flags);
|
||||||
|
|
||||||
/*! \name Object Containers
|
/*! \name Object Containers
|
||||||
* Here start declarations of containers.
|
* Here start declarations of containers.
|
||||||
@@ -910,7 +916,7 @@ struct ao2_container;
|
|||||||
*
|
*
|
||||||
* \param options Container ao2 object options (See enum ao2_alloc_opts)
|
* \param options Container ao2 object options (See enum ao2_alloc_opts)
|
||||||
* \param n_buckets Number of buckets for hash
|
* \param n_buckets Number of buckets for hash
|
||||||
* \param hash_fn Pointer to a function computing a hash value.
|
* \param hash_fn Pointer to a function computing a hash value. (NULL if everyting goes in first bucket.)
|
||||||
* \param cmp_fn Pointer to a compare function used by ao2_find. (NULL to match everything)
|
* \param cmp_fn Pointer to a compare function used by ao2_find. (NULL to match everything)
|
||||||
* \param tag used for debugging.
|
* \param tag used for debugging.
|
||||||
*
|
*
|
||||||
@@ -961,7 +967,7 @@ struct ao2_container *__ao2_container_alloc(unsigned int options,
|
|||||||
unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn);
|
unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn);
|
||||||
struct ao2_container *__ao2_container_alloc_debug(unsigned int options,
|
struct ao2_container *__ao2_container_alloc_debug(unsigned int options,
|
||||||
unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
|
unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
|
||||||
const char *tag, const char *file, int line, const char *funcname, int ref_debug);
|
const char *tag, const char *file, int line, const char *func, int ref_debug);
|
||||||
|
|
||||||
/*! \brief
|
/*! \brief
|
||||||
* Returns the number of elements in a container.
|
* Returns the number of elements in a container.
|
||||||
@@ -1002,7 +1008,7 @@ int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enu
|
|||||||
* \retval NULL on error.
|
* \retval NULL on error.
|
||||||
*/
|
*/
|
||||||
struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags);
|
struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags);
|
||||||
struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *funcname, int ref_debug);
|
struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func, int ref_debug);
|
||||||
#if defined(REF_DEBUG)
|
#if defined(REF_DEBUG)
|
||||||
|
|
||||||
#define ao2_t_container_clone(orig, flags, tag) __ao2_container_clone_debug(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
|
#define ao2_t_container_clone(orig, flags, tag) __ao2_container_clone_debug(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
|
||||||
@@ -1039,7 +1045,7 @@ struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, en
|
|||||||
* \param tag used for debugging.
|
* \param tag used for debugging.
|
||||||
*
|
*
|
||||||
* \retval NULL on errors.
|
* \retval NULL on errors.
|
||||||
* \retval newobj on success.
|
* \retval !NULL on success.
|
||||||
*
|
*
|
||||||
* This function inserts an object in a container according its key.
|
* This function inserts an object in a container according its key.
|
||||||
*
|
*
|
||||||
@@ -1066,8 +1072,8 @@ struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, en
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *__ao2_link_debug(struct ao2_container *c, void *new_obj, int flags, const char *tag, const char *file, int line, const char *funcname);
|
void *__ao2_link_debug(struct ao2_container *c, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func);
|
||||||
void *__ao2_link(struct ao2_container *c, void *newobj, int flags);
|
void *__ao2_link(struct ao2_container *c, void *obj_new, int flags);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Remove an object from a container
|
* \brief Remove an object from a container
|
||||||
@@ -1105,7 +1111,7 @@ void *__ao2_link(struct ao2_container *c, void *newobj, int flags);
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, const char *tag, const char *file, int line, const char *funcname);
|
void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, const char *tag, const char *file, int line, const char *func);
|
||||||
void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
|
void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
|
||||||
|
|
||||||
|
|
||||||
@@ -1121,10 +1127,10 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
|
|||||||
* the callback.
|
* the callback.
|
||||||
* - If OBJ_NODATA is set, ao2_callback will return NULL. No refcounts
|
* - If OBJ_NODATA is set, ao2_callback will return NULL. No refcounts
|
||||||
* of any of the traversed objects will be incremented.
|
* of any of the traversed objects will be incremented.
|
||||||
* On the converse, if it is NOT set (the default), The ref count
|
* On the converse, if it is NOT set (the default), the ref count
|
||||||
* of each object for which CMP_MATCH was set will be incremented,
|
* of the first matching object will be incremented and returned. If
|
||||||
* and you will have no way of knowing which those are, until
|
* OBJ_MULTIPLE is set, the ref count of all matching objects will
|
||||||
* the multiple-object-return functionality is implemented.
|
* be incremented in an iterator for a temporary container and returned.
|
||||||
* - If OBJ_POINTER is set, the traversed items will be restricted
|
* - If OBJ_POINTER is set, the traversed items will be restricted
|
||||||
* to the objects in the bucket that the object key hashes to.
|
* to the objects in the bucket that the object key hashes to.
|
||||||
* \param cb_fn A function pointer, that will be called on all
|
* \param cb_fn A function pointer, that will be called on all
|
||||||
@@ -1141,12 +1147,15 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
|
|||||||
* also used by ao2_callback).
|
* also used by ao2_callback).
|
||||||
* \param arg passed to the callback.
|
* \param arg passed to the callback.
|
||||||
* \param tag used for debugging.
|
* \param tag used for debugging.
|
||||||
* \return when OBJ_MULTIPLE is not included in the flags parameter,
|
*
|
||||||
* the return value will be either the object found or NULL if no
|
* \retval NULL on failure or no matching object found.
|
||||||
* no matching object was found. if OBJ_MULTIPLE is included,
|
*
|
||||||
* the return value will be a pointer to an ao2_iterator object,
|
* \retval object found if OBJ_MULTIPLE is not set in the flags
|
||||||
* which must be destroyed with ao2_iterator_destroy() when the
|
* parameter.
|
||||||
* caller no longer needs it.
|
*
|
||||||
|
* \retval ao2_iterator pointer if OBJ_MULTIPLE is set in the
|
||||||
|
* flags parameter. The iterator must be destroyed with
|
||||||
|
* ao2_iterator_destroy() when the caller no longer needs it.
|
||||||
*
|
*
|
||||||
* If the function returns any objects, their refcount is incremented,
|
* If the function returns any objects, their refcount is incremented,
|
||||||
* and the caller is in charge of decrementing them once done.
|
* and the caller is in charge of decrementing them once done.
|
||||||
@@ -1165,11 +1174,11 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
|
|||||||
* on objects according on flags passed.
|
* on objects according on flags passed.
|
||||||
* XXX describe better
|
* XXX describe better
|
||||||
* The comparison is done calling the compare function set implicitly.
|
* The comparison is done calling the compare function set implicitly.
|
||||||
* The p pointer can be a pointer to an object or to a key,
|
* The arg pointer can be a pointer to an object or to a key,
|
||||||
* we can say this looking at flags value.
|
* we can say this looking at flags value.
|
||||||
* If p points to an object we will search for the object pointed
|
* If arg points to an object we will search for the object pointed
|
||||||
* by this value, otherwise we search for a key value.
|
* by this value, otherwise we search for a key value.
|
||||||
* If the key is not unique we only find the first matching valued.
|
* If the key is not unique we only find the first matching value.
|
||||||
*
|
*
|
||||||
* The use of flags argument is the follow:
|
* The use of flags argument is the follow:
|
||||||
*
|
*
|
||||||
@@ -1205,7 +1214,7 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
|
|||||||
|
|
||||||
void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
|
void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
|
||||||
ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
|
ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
|
||||||
const char *funcname);
|
const char *func);
|
||||||
void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg);
|
void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg);
|
||||||
|
|
||||||
/*! @} */
|
/*! @} */
|
||||||
@@ -1243,7 +1252,7 @@ void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callb
|
|||||||
|
|
||||||
void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
|
void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
|
||||||
ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
|
ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
|
||||||
int line, const char *funcname);
|
int line, const char *func);
|
||||||
void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
|
void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
|
||||||
ao2_callback_data_fn *cb_fn, void *arg, void *data);
|
ao2_callback_data_fn *cb_fn, void *arg, void *data);
|
||||||
|
|
||||||
@@ -1267,7 +1276,7 @@ void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
|
void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
|
||||||
const char *tag, const char *file, int line, const char *funcname);
|
const char *tag, const char *file, int line, const char *func);
|
||||||
void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags);
|
void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags);
|
||||||
|
|
||||||
/*! \brief
|
/*! \brief
|
||||||
@@ -1384,11 +1393,13 @@ enum ao2_iterator_flags {
|
|||||||
* locked already.
|
* locked already.
|
||||||
*/
|
*/
|
||||||
AO2_ITERATOR_DONTLOCK = (1 << 0),
|
AO2_ITERATOR_DONTLOCK = (1 << 0),
|
||||||
/*! Indicates that the iterator was dynamically allocated by
|
/*!
|
||||||
|
* Indicates that the iterator was dynamically allocated by
|
||||||
* astobj2 API and should be freed by ao2_iterator_destroy().
|
* astobj2 API and should be freed by ao2_iterator_destroy().
|
||||||
*/
|
*/
|
||||||
AO2_ITERATOR_MALLOCD = (1 << 1),
|
AO2_ITERATOR_MALLOCD = (1 << 1),
|
||||||
/*! Indicates that before the iterator returns an object from
|
/*!
|
||||||
|
* Indicates that before the iterator returns an object from
|
||||||
* the container being iterated, the object should be unlinked
|
* the container being iterated, the object should be unlinked
|
||||||
* from the container.
|
* from the container.
|
||||||
*/
|
*/
|
||||||
@@ -1416,7 +1427,7 @@ struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
|
|||||||
/*!
|
/*!
|
||||||
* \brief Destroy a container iterator
|
* \brief Destroy a container iterator
|
||||||
*
|
*
|
||||||
* \param i the iterator to destroy
|
* \param iter the iterator to destroy
|
||||||
*
|
*
|
||||||
* \retval none
|
* \retval none
|
||||||
*
|
*
|
||||||
@@ -1425,9 +1436,9 @@ struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if defined(TEST_FRAMEWORK)
|
#if defined(TEST_FRAMEWORK)
|
||||||
void ao2_iterator_destroy(struct ao2_iterator *i) __attribute__((noinline));
|
void ao2_iterator_destroy(struct ao2_iterator *iter) __attribute__((noinline));
|
||||||
#else
|
#else
|
||||||
void ao2_iterator_destroy(struct ao2_iterator *i);
|
void ao2_iterator_destroy(struct ao2_iterator *iter);
|
||||||
#endif
|
#endif
|
||||||
#ifdef REF_DEBUG
|
#ifdef REF_DEBUG
|
||||||
|
|
||||||
@@ -1441,8 +1452,8 @@ void ao2_iterator_destroy(struct ao2_iterator *i);
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *__ao2_iterator_next_debug(struct ao2_iterator *a, const char *tag, const char *file, int line, const char *funcname);
|
void *__ao2_iterator_next_debug(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func);
|
||||||
void *__ao2_iterator_next(struct ao2_iterator *a);
|
void *__ao2_iterator_next(struct ao2_iterator *iter);
|
||||||
|
|
||||||
/* extra functions */
|
/* extra functions */
|
||||||
void ao2_bt(void); /* backtrace */
|
void ao2_bt(void); /* backtrace */
|
||||||
|
|||||||
163
main/astobj2.c
163
main/astobj2.c
@@ -414,7 +414,7 @@ void *ao2_object_get_lockaddr(void *user_data)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int internal_ao2_ref(void *user_data, int delta, const char *file, int line, const char *funcname)
|
static int internal_ao2_ref(void *user_data, int delta, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
struct astobj2 *obj = INTERNAL_OBJ(user_data);
|
struct astobj2 *obj = INTERNAL_OBJ(user_data);
|
||||||
struct astobj2_lock *obj_mutex;
|
struct astobj2_lock *obj_mutex;
|
||||||
@@ -446,7 +446,7 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
|
|||||||
|
|
||||||
/* this case must never happen */
|
/* this case must never happen */
|
||||||
if (current_value < 0) {
|
if (current_value < 0) {
|
||||||
ast_log(__LOG_ERROR, file, line, funcname,
|
ast_log(__LOG_ERROR, file, line, func,
|
||||||
"Invalid refcount %d on ao2 object %p\n", current_value, user_data);
|
"Invalid refcount %d on ao2 object %p\n", current_value, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,7 +495,7 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
|
|||||||
ast_free(obj);
|
ast_free(obj);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ast_log(__LOG_ERROR, file, line, funcname,
|
ast_log(__LOG_ERROR, file, line, func,
|
||||||
"Invalid lock option on ao2 object %p\n", user_data);
|
"Invalid lock option on ao2 object %p\n", user_data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -503,7 +503,7 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *file, int line, const char *funcname)
|
int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
struct astobj2 *obj = INTERNAL_OBJ(user_data);
|
struct astobj2 *obj = INTERNAL_OBJ(user_data);
|
||||||
|
|
||||||
@@ -514,18 +514,18 @@ int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *fil
|
|||||||
FILE *refo = fopen(REF_FILE, "a");
|
FILE *refo = fopen(REF_FILE, "a");
|
||||||
if (refo) {
|
if (refo) {
|
||||||
fprintf(refo, "%p %s%d %s:%d:%s (%s) [@%d]\n", user_data, (delta < 0 ? "" : "+"),
|
fprintf(refo, "%p %s%d %s:%d:%s (%s) [@%d]\n", user_data, (delta < 0 ? "" : "+"),
|
||||||
delta, file, line, funcname, tag, obj ? obj->priv_data.ref_counter : -1);
|
delta, file, line, func, tag, obj ? obj->priv_data.ref_counter : -1);
|
||||||
fclose(refo);
|
fclose(refo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (obj->priv_data.ref_counter + delta == 0 && obj->priv_data.destructor_fn != NULL) { /* this isn't protected with lock; just for o/p */
|
if (obj->priv_data.ref_counter + delta == 0 && obj->priv_data.destructor_fn != NULL) { /* this isn't protected with lock; just for o/p */
|
||||||
FILE *refo = fopen(REF_FILE, "a");
|
FILE *refo = fopen(REF_FILE, "a");
|
||||||
if (refo) {
|
if (refo) {
|
||||||
fprintf(refo, "%p **call destructor** %s:%d:%s (%s)\n", user_data, file, line, funcname, tag);
|
fprintf(refo, "%p **call destructor** %s:%d:%s (%s)\n", user_data, file, line, func, tag);
|
||||||
fclose(refo);
|
fclose(refo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return internal_ao2_ref(user_data, delta, file, line, funcname);
|
return internal_ao2_ref(user_data, delta, file, line, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __ao2_ref(void *user_data, int delta)
|
int __ao2_ref(void *user_data, int delta)
|
||||||
@@ -538,7 +538,7 @@ int __ao2_ref(void *user_data, int delta)
|
|||||||
return internal_ao2_ref(user_data, delta, __FILE__, __LINE__, __FUNCTION__);
|
return internal_ao2_ref(user_data, delta, __FILE__, __LINE__, __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *file, int line, const char *funcname)
|
static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
/* allocation */
|
/* allocation */
|
||||||
struct astobj2 *obj;
|
struct astobj2 *obj;
|
||||||
@@ -556,7 +556,7 @@ static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_f
|
|||||||
switch (options & AO2_ALLOC_OPT_LOCK_MASK) {
|
switch (options & AO2_ALLOC_OPT_LOCK_MASK) {
|
||||||
case AO2_ALLOC_OPT_LOCK_MUTEX:
|
case AO2_ALLOC_OPT_LOCK_MUTEX:
|
||||||
#if defined(__AST_DEBUG_MALLOC)
|
#if defined(__AST_DEBUG_MALLOC)
|
||||||
obj_mutex = __ast_calloc(1, sizeof(*obj_mutex) + data_size, file, line, funcname);
|
obj_mutex = __ast_calloc(1, sizeof(*obj_mutex) + data_size, file, line, func);
|
||||||
#else
|
#else
|
||||||
obj_mutex = ast_calloc(1, sizeof(*obj_mutex) + data_size);
|
obj_mutex = ast_calloc(1, sizeof(*obj_mutex) + data_size);
|
||||||
#endif
|
#endif
|
||||||
@@ -569,7 +569,7 @@ static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_f
|
|||||||
break;
|
break;
|
||||||
case AO2_ALLOC_OPT_LOCK_RWLOCK:
|
case AO2_ALLOC_OPT_LOCK_RWLOCK:
|
||||||
#if defined(__AST_DEBUG_MALLOC)
|
#if defined(__AST_DEBUG_MALLOC)
|
||||||
obj_rwlock = __ast_calloc(1, sizeof(*obj_rwlock) + data_size, file, line, funcname);
|
obj_rwlock = __ast_calloc(1, sizeof(*obj_rwlock) + data_size, file, line, func);
|
||||||
#else
|
#else
|
||||||
obj_rwlock = ast_calloc(1, sizeof(*obj_rwlock) + data_size);
|
obj_rwlock = ast_calloc(1, sizeof(*obj_rwlock) + data_size);
|
||||||
#endif
|
#endif
|
||||||
@@ -582,7 +582,7 @@ static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_f
|
|||||||
break;
|
break;
|
||||||
case AO2_ALLOC_OPT_LOCK_NOLOCK:
|
case AO2_ALLOC_OPT_LOCK_NOLOCK:
|
||||||
#if defined(__AST_DEBUG_MALLOC)
|
#if defined(__AST_DEBUG_MALLOC)
|
||||||
obj = __ast_calloc(1, sizeof(*obj) + data_size, file, line, funcname);
|
obj = __ast_calloc(1, sizeof(*obj) + data_size, file, line, func);
|
||||||
#else
|
#else
|
||||||
obj = ast_calloc(1, sizeof(*obj) + data_size);
|
obj = ast_calloc(1, sizeof(*obj) + data_size);
|
||||||
#endif
|
#endif
|
||||||
@@ -592,7 +592,7 @@ static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_f
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Invalid option value. */
|
/* Invalid option value. */
|
||||||
ast_log(__LOG_DEBUG, file, line, funcname, "Invalid lock option requested\n");
|
ast_log(__LOG_DEBUG, file, line, func, "Invalid lock option requested\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -614,18 +614,18 @@ static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_f
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag,
|
void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag,
|
||||||
const char *file, int line, const char *funcname, int ref_debug)
|
const char *file, int line, const char *func, int ref_debug)
|
||||||
{
|
{
|
||||||
/* allocation */
|
/* allocation */
|
||||||
void *obj;
|
void *obj;
|
||||||
FILE *refo;
|
FILE *refo;
|
||||||
|
|
||||||
if ((obj = internal_ao2_alloc(data_size, destructor_fn, options, file, line, funcname)) == NULL) {
|
if ((obj = internal_ao2_alloc(data_size, destructor_fn, options, file, line, func)) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ref_debug && (refo = fopen(REF_FILE, "a"))) {
|
if (ref_debug && (refo = fopen(REF_FILE, "a"))) {
|
||||||
fprintf(refo, "%p =1 %s:%d:%s (%s)\n", obj, file, line, funcname, tag);
|
fprintf(refo, "%p =1 %s:%d:%s (%s)\n", obj, file, line, func, tag);
|
||||||
fclose(refo);
|
fclose(refo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -807,13 +807,13 @@ static struct ao2_container *internal_ao2_container_alloc(struct ao2_container *
|
|||||||
|
|
||||||
struct ao2_container *__ao2_container_alloc_debug(unsigned int options,
|
struct ao2_container *__ao2_container_alloc_debug(unsigned int options,
|
||||||
unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
|
unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
|
||||||
const char *tag, const char *file, int line, const char *funcname, int ref_debug)
|
const char *tag, const char *file, int line, const char *func, int ref_debug)
|
||||||
{
|
{
|
||||||
/* XXX maybe consistency check on arguments ? */
|
/* XXX maybe consistency check on arguments ? */
|
||||||
/* compute the container size */
|
/* compute the container size */
|
||||||
unsigned int num_buckets = hash_fn ? n_buckets : 1;
|
unsigned int num_buckets = hash_fn ? n_buckets : 1;
|
||||||
size_t container_size = sizeof(struct ao2_container) + num_buckets * sizeof(struct bucket);
|
size_t container_size = sizeof(struct ao2_container) + num_buckets * sizeof(struct bucket);
|
||||||
struct ao2_container *c = __ao2_alloc_debug(container_size, container_destruct_debug, options, tag, file, line, funcname, ref_debug);
|
struct ao2_container *c = __ao2_alloc_debug(container_size, container_destruct_debug, options, tag, file, line, func, ref_debug);
|
||||||
|
|
||||||
return internal_ao2_container_alloc(c, num_buckets, hash_fn, cmp_fn);
|
return internal_ao2_container_alloc(c, num_buckets, hash_fn, cmp_fn);
|
||||||
}
|
}
|
||||||
@@ -841,7 +841,7 @@ int ao2_container_count(struct ao2_container *c)
|
|||||||
/*
|
/*
|
||||||
* link an object to a container
|
* link an object to a container
|
||||||
*/
|
*/
|
||||||
static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *user_data, int flags, const char *tag, const char *file, int line, const char *funcname)
|
static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *user_data, int flags, const char *tag, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
enum ao2_lock_req orig_lock;
|
enum ao2_lock_req orig_lock;
|
||||||
@@ -878,7 +878,7 @@ static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *use
|
|||||||
ast_atomic_fetchadd_int(&c->elements, 1);
|
ast_atomic_fetchadd_int(&c->elements, 1);
|
||||||
|
|
||||||
if (tag) {
|
if (tag) {
|
||||||
__ao2_ref_debug(user_data, +1, tag, file, line, funcname);
|
__ao2_ref_debug(user_data, +1, tag, file, line, func);
|
||||||
} else {
|
} else {
|
||||||
__ao2_ref(user_data, +1);
|
__ao2_ref(user_data, +1);
|
||||||
}
|
}
|
||||||
@@ -892,14 +892,14 @@ static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *use
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_link_debug(struct ao2_container *c, void *new_obj, int flags, const char *tag, const char *file, int line, const char *funcname)
|
void *__ao2_link_debug(struct ao2_container *c, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
return internal_ao2_link(c, new_obj, flags, tag, file, line, funcname);
|
return internal_ao2_link(c, obj_new, flags, tag, file, line, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_link(struct ao2_container *c, void *new_obj, int flags)
|
void *__ao2_link(struct ao2_container *c, void *obj_new, int flags)
|
||||||
{
|
{
|
||||||
return internal_ao2_link(c, new_obj, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
return internal_ao2_link(c, obj_new, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -915,14 +915,14 @@ int ao2_match_by_addr(void *user_data, void *arg, int flags)
|
|||||||
* and destroy the associated * bucket_entry structure.
|
* and destroy the associated * bucket_entry structure.
|
||||||
*/
|
*/
|
||||||
void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, int flags,
|
void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, int flags,
|
||||||
const char *tag, const char *file, int line, const char *funcname)
|
const char *tag, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
if (INTERNAL_OBJ(user_data) == NULL) { /* safety check on the argument */
|
if (INTERNAL_OBJ(user_data) == NULL) { /* safety check on the argument */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= (OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA);
|
flags |= (OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA);
|
||||||
__ao2_callback_debug(c, flags, ao2_match_by_addr, user_data, tag, file, line, funcname);
|
__ao2_callback_debug(c, flags, ao2_match_by_addr, user_data, tag, file, line, func);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -959,13 +959,13 @@ static int cb_true_data(void *user_data, void *arg, void *data, int flags)
|
|||||||
* 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
|
||||||
* specified.
|
* specified.
|
||||||
* Luckily, for debug purposes, the added args (tag, file, line, funcname)
|
* Luckily, for debug purposes, the added args (tag, file, line, func)
|
||||||
* aren't an excessive load to the system, as the callback should not be
|
* aren't an excessive load to the system, as the callback should not be
|
||||||
* called as often as, say, the ao2_ref func is called.
|
* called as often as, say, the ao2_ref func is called.
|
||||||
*/
|
*/
|
||||||
static void *internal_ao2_callback(struct ao2_container *c, enum search_flags flags,
|
static void *internal_ao2_callback(struct ao2_container *c, enum search_flags flags,
|
||||||
void *cb_fn, void *arg, void *data, enum ao2_callback_type type, const char *tag,
|
void *cb_fn, void *arg, void *data, enum ao2_callback_type type, const char *tag,
|
||||||
const char *file, int line, const char *funcname)
|
const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
int i, start, last; /* search boundaries */
|
int i, start, last; /* search boundaries */
|
||||||
enum ao2_lock_req orig_lock;
|
enum ao2_lock_req orig_lock;
|
||||||
@@ -1085,10 +1085,11 @@ static void *internal_ao2_callback(struct ao2_container *c, enum search_flags fl
|
|||||||
/* it is important to handle this case before the unlink */
|
/* it is important to handle this case before the unlink */
|
||||||
ret = EXTERNAL_OBJ(cur->astobj);
|
ret = EXTERNAL_OBJ(cur->astobj);
|
||||||
if (!(flags & (OBJ_UNLINK | OBJ_MULTIPLE))) {
|
if (!(flags & (OBJ_UNLINK | OBJ_MULTIPLE))) {
|
||||||
if (tag)
|
if (tag) {
|
||||||
__ao2_ref_debug(ret, 1, tag, file, line, funcname);
|
__ao2_ref_debug(ret, 1, tag, file, line, func);
|
||||||
else
|
} else {
|
||||||
__ao2_ref(ret, 1);
|
__ao2_ref(ret, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1097,7 +1098,7 @@ static void *internal_ao2_callback(struct ao2_container *c, enum search_flags fl
|
|||||||
*/
|
*/
|
||||||
if (ret && (multi_container != NULL)) {
|
if (ret && (multi_container != NULL)) {
|
||||||
if (tag) {
|
if (tag) {
|
||||||
__ao2_link_debug(multi_container, ret, flags, tag, file, line, funcname);
|
__ao2_link_debug(multi_container, ret, flags, tag, file, line, func);
|
||||||
} else {
|
} else {
|
||||||
__ao2_link(multi_container, ret, flags);
|
__ao2_link(multi_container, ret, flags);
|
||||||
}
|
}
|
||||||
@@ -1119,7 +1120,7 @@ static void *internal_ao2_callback(struct ao2_container *c, enum search_flags fl
|
|||||||
* from the original container is not accounted for here a memory leak occurs. */
|
* from the original container is not accounted for here a memory leak occurs. */
|
||||||
if (flags & (OBJ_NODATA | OBJ_MULTIPLE)) {
|
if (flags & (OBJ_NODATA | OBJ_MULTIPLE)) {
|
||||||
if (tag)
|
if (tag)
|
||||||
__ao2_ref_debug(EXTERNAL_OBJ(cur->astobj), -1, tag, file, line, funcname);
|
__ao2_ref_debug(EXTERNAL_OBJ(cur->astobj), -1, tag, file, line, func);
|
||||||
else
|
else
|
||||||
__ao2_ref(EXTERNAL_OBJ(cur->astobj), -1);
|
__ao2_ref(EXTERNAL_OBJ(cur->astobj), -1);
|
||||||
}
|
}
|
||||||
@@ -1165,9 +1166,9 @@ static void *internal_ao2_callback(struct ao2_container *c, enum search_flags fl
|
|||||||
|
|
||||||
void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
|
void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
|
||||||
ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
|
ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
|
||||||
const char *funcname)
|
const char *func)
|
||||||
{
|
{
|
||||||
return internal_ao2_callback(c,flags, cb_fn, arg, NULL, DEFAULT, tag, file, line, funcname);
|
return internal_ao2_callback(c,flags, cb_fn, arg, NULL, DEFAULT, tag, file, line, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
|
void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
|
||||||
@@ -1178,9 +1179,9 @@ void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
|
|||||||
|
|
||||||
void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
|
void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
|
||||||
ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
|
ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
|
||||||
int line, const char *funcname)
|
int line, const char *func)
|
||||||
{
|
{
|
||||||
return internal_ao2_callback(c, flags, cb_fn, arg, data, WITH_DATA, tag, file, line, funcname);
|
return internal_ao2_callback(c, flags, cb_fn, arg, data, WITH_DATA, tag, file, line, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
|
void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
|
||||||
@@ -1193,11 +1194,11 @@ void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
|
|||||||
* the find function just invokes the default callback with some reasonable flags.
|
* the find function just invokes the default callback with some reasonable flags.
|
||||||
*/
|
*/
|
||||||
void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
|
void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
|
||||||
const char *tag, const char *file, int line, const char *funcname)
|
const char *tag, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
void *arged = (void *) arg;/* Done to avoid compiler const warning */
|
void *arged = (void *) arg;/* Done to avoid compiler const warning */
|
||||||
|
|
||||||
return __ao2_callback_debug(c, flags, c->cmp_fn, arged, tag, file, line, funcname);
|
return __ao2_callback_debug(c, flags, c->cmp_fn, arged, tag, file, line, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags)
|
void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags)
|
||||||
@@ -1225,59 +1226,59 @@ struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
|
|||||||
/*!
|
/*!
|
||||||
* destroy an iterator
|
* destroy an iterator
|
||||||
*/
|
*/
|
||||||
void ao2_iterator_destroy(struct ao2_iterator *i)
|
void ao2_iterator_destroy(struct ao2_iterator *iter)
|
||||||
{
|
{
|
||||||
ao2_ref(i->c, -1);
|
ao2_ref(iter->c, -1);
|
||||||
if (i->flags & AO2_ITERATOR_MALLOCD) {
|
if (iter->flags & AO2_ITERATOR_MALLOCD) {
|
||||||
ast_free(i);
|
ast_free(iter);
|
||||||
} else {
|
} else {
|
||||||
i->c = NULL;
|
iter->c = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* move to the next element in the container.
|
* move to the next element in the container.
|
||||||
*/
|
*/
|
||||||
static void *internal_ao2_iterator_next(struct ao2_iterator *a, const char *tag, const char *file, int line, const char *funcname)
|
static void *internal_ao2_iterator_next(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
int lim;
|
int lim;
|
||||||
enum ao2_lock_req orig_lock;
|
enum ao2_lock_req orig_lock;
|
||||||
struct bucket_entry *p = NULL;
|
struct bucket_entry *p = NULL;
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if (INTERNAL_OBJ(a->c) == NULL) {
|
if (INTERNAL_OBJ(iter->c) == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->flags & AO2_ITERATOR_DONTLOCK) {
|
if (iter->flags & AO2_ITERATOR_DONTLOCK) {
|
||||||
if (a->flags & AO2_ITERATOR_UNLINK) {
|
if (iter->flags & AO2_ITERATOR_UNLINK) {
|
||||||
orig_lock = adjust_lock(a->c, AO2_LOCK_REQ_WRLOCK, 1);
|
orig_lock = adjust_lock(iter->c, AO2_LOCK_REQ_WRLOCK, 1);
|
||||||
} else {
|
} else {
|
||||||
orig_lock = adjust_lock(a->c, AO2_LOCK_REQ_RDLOCK, 1);
|
orig_lock = adjust_lock(iter->c, AO2_LOCK_REQ_RDLOCK, 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
orig_lock = AO2_LOCK_REQ_MUTEX;
|
orig_lock = AO2_LOCK_REQ_MUTEX;
|
||||||
if (a->flags & AO2_ITERATOR_UNLINK) {
|
if (iter->flags & AO2_ITERATOR_UNLINK) {
|
||||||
ao2_wrlock(a->c);
|
ao2_wrlock(iter->c);
|
||||||
} else {
|
} else {
|
||||||
ao2_rdlock(a->c);
|
ao2_rdlock(iter->c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* optimization. If the container is unchanged and
|
/* optimization. If the container is unchanged and
|
||||||
* we have a pointer, try follow it
|
* we have a pointer, try follow it
|
||||||
*/
|
*/
|
||||||
if (a->c->version == a->c_version && (p = a->obj)) {
|
if (iter->c->version == iter->c_version && (p = iter->obj)) {
|
||||||
if ((p = AST_LIST_NEXT(p, entry))) {
|
if ((p = AST_LIST_NEXT(p, entry))) {
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
/* nope, start from the next bucket */
|
/* nope, start from the next bucket */
|
||||||
a->bucket++;
|
iter->bucket++;
|
||||||
a->version = 0;
|
iter->version = 0;
|
||||||
a->obj = NULL;
|
iter->obj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lim = a->c->n_buckets;
|
lim = iter->c->n_buckets;
|
||||||
|
|
||||||
/* Browse the buckets array, moving to the next
|
/* Browse the buckets array, moving to the next
|
||||||
* buckets if we don't find the entry in the current one.
|
* buckets if we don't find the entry in the current one.
|
||||||
@@ -1285,10 +1286,10 @@ static void *internal_ao2_iterator_next(struct ao2_iterator *a, const char *tag,
|
|||||||
* than the current one (we reset the version to 0 when we
|
* than the current one (we reset the version to 0 when we
|
||||||
* switch buckets).
|
* switch buckets).
|
||||||
*/
|
*/
|
||||||
for (; a->bucket < lim; a->bucket++, a->version = 0) {
|
for (; iter->bucket < lim; iter->bucket++, iter->version = 0) {
|
||||||
/* scan the current bucket */
|
/* scan the current bucket */
|
||||||
AST_LIST_TRAVERSE(&a->c->buckets[a->bucket], p, entry) {
|
AST_LIST_TRAVERSE(&iter->c->buckets[iter->bucket], p, entry) {
|
||||||
if (p->version > a->version) {
|
if (p->version > iter->version) {
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1297,24 +1298,24 @@ static void *internal_ao2_iterator_next(struct ao2_iterator *a, const char *tag,
|
|||||||
found:
|
found:
|
||||||
if (p) {
|
if (p) {
|
||||||
ret = EXTERNAL_OBJ(p->astobj);
|
ret = EXTERNAL_OBJ(p->astobj);
|
||||||
if (a->flags & AO2_ITERATOR_UNLINK) {
|
if (iter->flags & AO2_ITERATOR_UNLINK) {
|
||||||
/* we are going to modify the container, so update version */
|
/* we are going to modify the container, so update version */
|
||||||
ast_atomic_fetchadd_int(&a->c->version, 1);
|
ast_atomic_fetchadd_int(&iter->c->version, 1);
|
||||||
AST_LIST_REMOVE(&a->c->buckets[a->bucket], p, entry);
|
AST_LIST_REMOVE(&iter->c->buckets[iter->bucket], p, entry);
|
||||||
/* update number of elements */
|
/* update number of elements */
|
||||||
ast_atomic_fetchadd_int(&a->c->elements, -1);
|
ast_atomic_fetchadd_int(&iter->c->elements, -1);
|
||||||
a->version = 0;
|
iter->version = 0;
|
||||||
a->obj = NULL;
|
iter->obj = NULL;
|
||||||
a->c_version = a->c->version;
|
iter->c_version = iter->c->version;
|
||||||
ast_free(p);
|
ast_free(p);
|
||||||
} else {
|
} else {
|
||||||
a->version = p->version;
|
iter->version = p->version;
|
||||||
a->obj = p;
|
iter->obj = p;
|
||||||
a->c_version = a->c->version;
|
iter->c_version = iter->c->version;
|
||||||
|
|
||||||
/* inc refcount of returned object */
|
/* inc refcount of returned object */
|
||||||
if (tag) {
|
if (tag) {
|
||||||
__ao2_ref_debug(ret, 1, tag, file, line, funcname);
|
__ao2_ref_debug(ret, 1, tag, file, line, func);
|
||||||
} else {
|
} else {
|
||||||
__ao2_ref(ret, 1);
|
__ao2_ref(ret, 1);
|
||||||
}
|
}
|
||||||
@@ -1323,23 +1324,23 @@ found:
|
|||||||
ret = NULL;
|
ret = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->flags & AO2_ITERATOR_DONTLOCK) {
|
if (iter->flags & AO2_ITERATOR_DONTLOCK) {
|
||||||
adjust_lock(a->c, orig_lock, 0);
|
adjust_lock(iter->c, orig_lock, 0);
|
||||||
} else {
|
} else {
|
||||||
ao2_unlock(a->c);
|
ao2_unlock(iter->c);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_iterator_next_debug(struct ao2_iterator *a, const char *tag, const char *file, int line, const char *funcname)
|
void *__ao2_iterator_next_debug(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func)
|
||||||
{
|
{
|
||||||
return internal_ao2_iterator_next(a, tag, file, line, funcname);
|
return internal_ao2_iterator_next(iter, tag, file, line, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *__ao2_iterator_next(struct ao2_iterator *a)
|
void *__ao2_iterator_next(struct ao2_iterator *iter)
|
||||||
{
|
{
|
||||||
return internal_ao2_iterator_next(a, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
return internal_ao2_iterator_next(iter, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* callback for destroying container.
|
/* callback for destroying container.
|
||||||
@@ -1477,7 +1478,7 @@ struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum sea
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *funcname, int ref_debug)
|
struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func, int ref_debug)
|
||||||
{
|
{
|
||||||
struct ao2_container *clone;
|
struct ao2_container *clone;
|
||||||
struct astobj2 *orig_obj;
|
struct astobj2 *orig_obj;
|
||||||
@@ -1492,7 +1493,7 @@ struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, en
|
|||||||
|
|
||||||
/* Create the clone container with the same properties as the original. */
|
/* Create the clone container with the same properties as the original. */
|
||||||
clone = __ao2_container_alloc_debug(options, orig->n_buckets, orig->hash_fn,
|
clone = __ao2_container_alloc_debug(options, orig->n_buckets, orig->hash_fn,
|
||||||
orig->cmp_fn, tag, file, line, funcname, ref_debug);
|
orig->cmp_fn, tag, file, line, func, ref_debug);
|
||||||
if (!clone) {
|
if (!clone) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1507,7 +1508,7 @@ struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, en
|
|||||||
if (failed) {
|
if (failed) {
|
||||||
/* Object copy into the clone container failed. */
|
/* Object copy into the clone container failed. */
|
||||||
if (ref_debug) {
|
if (ref_debug) {
|
||||||
__ao2_ref_debug(clone, -1, tag, file, line, funcname);
|
__ao2_ref_debug(clone, -1, tag, file, line, func);
|
||||||
} else {
|
} else {
|
||||||
__ao2_ref(clone, -1);
|
__ao2_ref(clone, -1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user