astobj2.h documentation updates.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@356734 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Richard Mudgett
2012-02-24 20:47:12 +00:00
parent ebe2c33b72
commit e43d123f11
2 changed files with 212 additions and 169 deletions

View File

@@ -209,33 +209,37 @@ were called to appear in /tmp/refs, you can do this sort of thing:
#define dialog_unref(arg1,arg2) dialog_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__) #define dialog_unref(arg1,arg2) dialog_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
static struct sip_pvt *dialog_ref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func) static struct sip_pvt *dialog_ref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
{ {
if (p) if (p) {
ao2_ref_debug(p, 1, tag, file, line, func); ao2_ref_debug(p, 1, tag, file, line, func);
else } else {
ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
}
return p; return p;
} }
static struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func) static struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
{ {
if (p) if (p) {
ao2_ref_debug(p, -1, tag, file, line, func); ao2_ref_debug(p, -1, tag, file, line, func);
}
return NULL; return NULL;
} }
#else #else
static struct sip_pvt *dialog_ref(struct sip_pvt *p, const char *tag) static struct sip_pvt *dialog_ref(struct sip_pvt *p, const char *tag)
{ {
if (p) if (p) {
ao2_ref(p, 1); ao2_ref(p, 1);
else } else {
ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
}
return p; return p;
} }
static struct sip_pvt *dialog_unref(struct sip_pvt *p, const char *tag) static struct sip_pvt *dialog_unref(struct sip_pvt *p, const char *tag)
{ {
if (p) if (p) {
ao2_ref(p, -1); ao2_ref(p, -1);
}
return NULL; return NULL;
} }
#endif #endif
@@ -332,16 +336,19 @@ Example:
*//* Unlink us from the owner (channel) if we have one *//* *//* Unlink us from the owner (channel) if we have one *//*
if (dialog->owner) { if (dialog->owner) {
if (lockowner) if (lockowner) {
ast_channel_lock(dialog->owner); ast_channel_lock(dialog->owner);
}
ast_debug(1, "Detaching from channel %s\n", dialog->owner->name); ast_debug(1, "Detaching from channel %s\n", dialog->owner->name);
dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all"); dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
if (lockowner) if (lockowner) {
ast_channel_unlock(dialog->owner); ast_channel_unlock(dialog->owner);
} }
}
if (dialog->registry) { if (dialog->registry) {
if (dialog->registry->call == dialog) if (dialog->registry->call == dialog) {
dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all"); dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
}
dialog->registry = registry_unref(dialog->registry, "delete dialog->registry"); dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
} }
... ...
@@ -384,14 +391,15 @@ murf
typedef void (*ao2_destructor_fn)(void *); typedef void (*ao2_destructor_fn)(void *);
/*! \brief /*!
* Allocate and initialize an object. * \brief Allocate and initialize an object.
* *
* \param data_size The sizeof() of the user-defined structure. * \param data_size The sizeof() of the user-defined structure.
* \param destructor_fn The destructor function (can be NULL) * \param destructor_fn The destructor function (can be NULL)
* \param debug_msg * \param debug_msg Ao2 object debug tracing message.
* \return A pointer to user-data. * \return A pointer to user-data.
* *
* \details
* Allocates a struct astobj2 with sufficient space for the * Allocates a struct astobj2 with sufficient space for the
* user-defined structure. * user-defined structure.
* \note * \note
@@ -405,24 +413,30 @@ typedef void (*ao2_destructor_fn)(void *);
#if defined(REF_DEBUG) #if defined(REF_DEBUG)
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 1) #define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
#define ao2_alloc(data_size, destructor_fn) __ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
#define ao2_alloc(data_size, destructor_fn) \
__ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
#elif defined(__AST_DEBUG_MALLOC) #elif defined(__AST_DEBUG_MALLOC)
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) #define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
#define ao2_alloc(data_size, destructor_fn) __ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
#define ao2_alloc(data_size, destructor_fn) \
__ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
#else #else
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc((data_size), (destructor_fn)) #define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
#define ao2_alloc(data_size, destructor_fn) __ao2_alloc((data_size), (destructor_fn)) __ao2_alloc((data_size), (destructor_fn))
#define ao2_alloc(data_size, destructor_fn) \
__ao2_alloc((data_size), (destructor_fn))
#endif #endif
void *__ao2_alloc_debug(const size_t data_size, ao2_destructor_fn destructor_fn, const char *tag, void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, const char *tag,
const char *file, int line, const char *funcname, int ref_debug); const char *file, int line, const char *funcname, int ref_debug);
void *__ao2_alloc(const size_t data_size, ao2_destructor_fn destructor_fn); void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn);
/*! @} */ /*! @} */
@@ -495,10 +509,10 @@ int __ao2_trylock(void *a, const char *file, const char *func, int line, const c
#define ao2_trylock(a) __ao2_trylock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a) #define ao2_trylock(a) __ao2_trylock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
/*! /*!
* \brief Return the lock address of an object * \brief Return the mutex lock address of an object
* *
* \param[in] obj A pointer to the object we want. * \param[in] obj A pointer to the object we want.
* \return the address of the lock, else NULL. * \return the address of the mutex lock, else NULL.
* *
* This function comes in handy mainly for debugging locking * This function comes in handy mainly for debugging locking
* situations, where the locking trace code reports the * situations, where the locking trace code reports the
@@ -532,7 +546,7 @@ Operations on container include:
takes two argument, the object pointer and a flags field, takes two argument, the object pointer and a flags field,
- \b ao2_find(c, arg, flags) - \b ao2_find(c, arg, flags)
returns zero or more element matching a given criteria returns zero or more elements matching a given criteria
(specified as arg). 'c' is the container pointer. Flags (specified as arg). 'c' is the container pointer. Flags
can be: can be:
OBJ_UNLINK - to remove the object, once found, from the container. OBJ_UNLINK - to remove the object, once found, from the container.
@@ -540,6 +554,8 @@ Operations on container include:
OBJ_MULTIPLE - don't stop at first match OBJ_MULTIPLE - don't stop at first match
OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table
search will be done. If not, a traversal is done. search will be done. If not, a traversal is done.
OBJ_KEY - if set, 'arg', is a hashable item that is not an object.
Similar to OBJ_POINTER and mutually exclusive.
- \b ao2_callback(c, flags, fn, arg) - \b ao2_callback(c, flags, fn, arg)
apply fn(obj, arg) to all objects in the container. apply fn(obj, arg) to all objects in the container.
@@ -553,6 +569,8 @@ Operations on container include:
OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table
search will be done. If not, a traversal is done through search will be done. If not, a traversal is done through
all the hash table 'buckets'.. all the hash table 'buckets'..
OBJ_KEY - if set, 'arg', is a hashable item that is not an object.
Similar to OBJ_POINTER and mutually exclusive.
- fn is a func that returns int, and takes 3 args: - fn is a func that returns int, and takes 3 args:
(void *obj, void *arg, int flags); (void *obj, void *arg, int flags);
obj is an object obj is an object
@@ -683,9 +701,11 @@ enum search_flags {
/*! /*!
* \brief The data is hashable, but is not an object. * \brief The data is hashable, but is not an object.
* *
* \details
* This can be used when you want to be able to pass custom data * This can be used when you want to be able to pass custom data
* to a hash function that is not a full object, but perhaps just * to the container's stored ao2_hash_fn and ao2_find
* a string. * ao2_callback_fn functions that is not a full object, but
* perhaps just a string.
* *
* \note OBJ_KEY and OBJ_POINTER are mutually exclusive options. * \note OBJ_KEY and OBJ_POINTER are mutually exclusive options.
*/ */
@@ -705,17 +725,17 @@ typedef int (ao2_hash_fn)(const void *obj, const int flags);
/*@{ */ /*@{ */
struct ao2_container; struct ao2_container;
/*! \brief /*!
* Allocate and initialize a container * \brief Allocate and initialize a hash container with the desired number of buckets.
* with the desired number of buckets.
* *
* \details
* We allocate space for a struct astobj_container, struct container * We allocate space for a struct astobj_container, struct container
* and the buckets[] array. * and the buckets[] array.
* *
* \param arg1 Number of buckets for hash * \param n_buckets Number of buckets for hash
* \param arg2 Pointer to a function computing a hash value. * \param hash_fn Pointer to a function computing a hash value.
* \param arg3 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 arg4 used for debugging. * \param tag used for debugging.
* *
* \return A pointer to a struct container. * \return A pointer to a struct container.
* *
@@ -724,27 +744,32 @@ struct ao2_container;
#if defined(REF_DEBUG) #if defined(REF_DEBUG)
#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4), __FILE__, __LINE__, __PRETTY_FUNCTION__, 1) #define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \
#define ao2_container_alloc(arg1,arg2,arg3) __ao2_container_alloc_debug((arg1), (arg2), (arg3), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1) __ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
#define ao2_container_alloc(n_buckets, hash_fn, cmp_fn) \
__ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
#elif defined(__AST_DEBUG_MALLOC) #elif defined(__AST_DEBUG_MALLOC)
#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4), __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) #define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \
#define ao2_container_alloc(arg1,arg2,arg3) __ao2_container_alloc_debug((arg1), (arg2), (arg3), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) __ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
#define ao2_container_alloc(n_buckets, hash_fn, cmp_fn) \
__ao2_container_alloc_debug((n_buckets), (hash_fn), (cmp_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
#else #else
#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc((arg1), (arg2), (arg3)) #define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \
#define ao2_container_alloc(arg1,arg2,arg3) __ao2_container_alloc((arg1), (arg2), (arg3)) __ao2_container_alloc((n_buckets), (hash_fn), (cmp_fn))
#define ao2_container_alloc(n_buckets, hash_fn, cmp_fn) \
__ao2_container_alloc((n_buckets), (hash_fn), (cmp_fn))
#endif #endif
struct ao2_container *__ao2_container_alloc(const unsigned int n_buckets, struct ao2_container *__ao2_container_alloc(unsigned int n_buckets, ao2_hash_fn *hash_fn,
ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn); ao2_callback_fn *cmp_fn);
struct ao2_container *__ao2_container_alloc_debug(const unsigned int n_buckets, struct ao2_container *__ao2_container_alloc_debug(unsigned int n_buckets,
ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
const char *tag, char *file, int line, const char *funcname, const char *tag, char *file, int line, const char *funcname, int ref_debug);
int ref_debug);
/*! \brief /*! \brief
* Returns the number of elements in a container. * Returns the number of elements in a container.
@@ -764,9 +789,9 @@ int ao2_container_count(struct ao2_container *c);
/*! /*!
* \brief Add an object to a container. * \brief Add an object to a container.
* *
* \param arg1 the container to operate on. * \param container The container to operate on.
* \param arg2 the object to be added. * \param obj The object to be added.
* \param arg3 used for debugging. * \param tag used for debugging.
* *
* \retval NULL on errors. * \retval NULL on errors.
* \retval newobj on success. * \retval newobj on success.
@@ -780,17 +805,19 @@ int ao2_container_count(struct ao2_container *c);
*/ */
#ifdef REF_DEBUG #ifdef REF_DEBUG
#define ao2_t_link(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), 0, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_link(container, obj, tag) __ao2_link_debug((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_link(arg1, arg2) __ao2_link_debug((arg1), (arg2), 0, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_link(container, obj) __ao2_link_debug((container), (obj), 0, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_t_link_nolock(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), OBJ_NOLOCK, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_link_nolock(arg1, arg2) __ao2_link_debug((arg1), (arg2), OBJ_NOLOCK, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_link_nolock(container, obj, tag) __ao2_link_debug((container), (obj), OBJ_NOLOCK, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_link_nolock(container, obj) __ao2_link_debug((container), (obj), OBJ_NOLOCK, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else #else
#define ao2_t_link(arg1, arg2, arg3) __ao2_link((arg1), (arg2), 0) #define ao2_t_link(container, obj, tag) __ao2_link((container), (obj), 0)
#define ao2_link(arg1, arg2) __ao2_link((arg1), (arg2), 0) #define ao2_link(container, obj) __ao2_link((container), (obj), 0)
#define ao2_t_link_nolock(arg1, arg2, arg3) __ao2_link((arg1), (arg2), OBJ_NOLOCK)
#define ao2_link_nolock(arg1, arg2) __ao2_link((arg1), (arg2), OBJ_NOLOCK) #define ao2_t_link_nolock(container, obj, tag) __ao2_link((container), (obj), OBJ_NOLOCK)
#define ao2_link_nolock(container, obj) __ao2_link((container), (obj), OBJ_NOLOCK)
#endif #endif
@@ -800,9 +827,9 @@ void *__ao2_link(struct ao2_container *c, void *newobj, int flags);
/*! /*!
* \brief Remove an object from a container * \brief Remove an object from a container
* *
* \param arg1 the container * \param container The container to operate on.
* \param arg2 the object to unlink * \param obj The object to unlink.
* \param arg3 tag for debugging * \param tag used for debugging.
* *
* \retval NULL, always * \retval NULL, always
* *
@@ -816,17 +843,19 @@ void *__ao2_link(struct ao2_container *c, void *newobj, int flags);
*/ */
#ifdef REF_DEBUG #ifdef REF_DEBUG
#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink_debug((arg1), (arg2), 0, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_unlink(container, obj, tag) __ao2_unlink_debug((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_unlink(arg1, arg2) __ao2_unlink_debug((arg1), (arg2), 0, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_unlink(container, obj) __ao2_unlink_debug((container), (obj), 0, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_t_unlink_nolock(arg1, arg2, arg3) __ao2_unlink_debug((arg1), (arg2), OBJ_NOLOCK, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_unlink_nolock(arg1, arg2) __ao2_unlink_debug((arg1), (arg2), OBJ_NOLOCK, "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_unlink_nolock(container, obj, tag) __ao2_unlink_debug((container), (obj), OBJ_NOLOCK, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_unlink_nolock(container, obj) __ao2_unlink_debug((container), (obj), OBJ_NOLOCK, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else #else
#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink((arg1), (arg2), 0) #define ao2_t_unlink(container, obj, tag) __ao2_unlink((container), (obj), 0)
#define ao2_unlink(arg1, arg2) __ao2_unlink((arg1), (arg2), 0) #define ao2_unlink(container, obj) __ao2_unlink((container), (obj), 0)
#define ao2_t_unlink_nolock(arg1, arg2, arg3) __ao2_unlink((arg1), (arg2), OBJ_NOLOCK)
#define ao2_unlink_nolock(arg1, arg2) __ao2_unlink((arg1), (arg2), OBJ_NOLOCK) #define ao2_t_unlink_nolock(container, obj, tag) __ao2_unlink((container), (obj), OBJ_NOLOCK)
#define ao2_unlink_nolock(container, obj) __ao2_unlink((container), (obj), OBJ_NOLOCK)
#endif #endif
@@ -842,28 +871,28 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
* *
* \param c A pointer to the container to operate on. * \param c A pointer to the container to operate on.
* \param flags A set of flags specifying the operation to perform, * \param flags A set of flags specifying the operation to perform,
partially used by the container code, but also passed to * partially used by the container code, but also passed to
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 each object for which CMP_MATCH was set will be incremented,
and you will have no way of knowing which those are, until * and you will have no way of knowing which those are, until
the multiple-object-return functionality is implemented. * the multiple-object-return functionality is implemented.
- 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
objects, to see if they match. This function returns CMP_MATCH * objects, to see if they match. This function returns CMP_MATCH
if the object is matches the criteria; CMP_STOP if the traversal * if the object is matches the criteria; CMP_STOP if the traversal
should immediately stop, or both (via bitwise ORing), if you find a * should immediately stop, or both (via bitwise ORing), if you find a
match and want to end the traversal, and 0 if the object is not a match, * match and want to end the traversal, and 0 if the object is not a match,
but the traversal should continue. This is the function that is applied * but the traversal should continue. This is the function that is applied
to each object traversed. Its arguments are: * to each object traversed. Its arguments are:
(void *obj, void *arg, int flags), where: * (void *obj, void *arg, int flags), where:
obj is an object * obj is an object
arg is the same as arg passed into ao2_callback * arg is the same as arg passed into ao2_callback
flags is the same as flags passed into ao2_callback (flags are * flags is the same as flags passed into ao2_callback (flags are
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, * \return when OBJ_MULTIPLE is not included in the flags parameter,
@@ -885,7 +914,7 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
* should not modify the object, but just return a combination of * should not modify the object, but just return a combination of
* CMP_MATCH and CMP_STOP on the desired object. * CMP_MATCH and CMP_STOP on the desired object.
* Other usages are also possible, of course. * Other usages are also possible, of course.
*
* This function searches through a container and performs operations * This function searches through a container and performs operations
* on objects according on flags passed. * on objects according on flags passed.
* XXX describe better * XXX describe better
@@ -905,6 +934,7 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
* OBJ_MULTIPLE return multiple matches * OBJ_MULTIPLE return multiple matches
* Default is no. * Default is no.
* OBJ_POINTER the pointer is an object pointer * OBJ_POINTER the pointer is an object pointer
* OBJ_KEY the pointer is to a hashable key
* *
* \note When the returned object is no longer in use, ao2_ref() should * \note When the returned object is no longer in use, ao2_ref() should
* be used to free the additional reference possibly created by this function. * be used to free the additional reference possibly created by this function.
@@ -913,18 +943,23 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
*/ */
#ifdef REF_DEBUG #ifdef REF_DEBUG
#define ao2_t_callback(c,flags,cb_fn,arg,tag) __ao2_callback_debug((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_callback(c, flags, cb_fn, arg, tag) \
#define ao2_callback(c,flags,cb_fn,arg) __ao2_callback_debug((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) __ao2_callback_debug((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_callback(c, flags, cb_fn, arg) \
__ao2_callback_debug((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else #else
#define ao2_t_callback(c,flags,cb_fn,arg,tag) __ao2_callback((c), (flags), (cb_fn), (arg)) #define ao2_t_callback(c, flags, cb_fn, arg, tag) \
#define ao2_callback(c,flags,cb_fn,arg) __ao2_callback((c), (flags), (cb_fn), (arg)) __ao2_callback((c), (flags), (cb_fn), (arg))
#define ao2_callback(c, flags, cb_fn, arg) \
__ao2_callback((c), (flags), (cb_fn), (arg))
#endif #endif
void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
void *arg, const char *tag, char *file, int line, const char *funcname); ao2_callback_fn *cb_fn, void *arg, const char *tag, char *file, int line,
const char *funcname);
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);
/*! @} */ /*! @} */
@@ -946,19 +981,23 @@ void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callb
*/ */
#ifdef REF_DEBUG #ifdef REF_DEBUG
#define ao2_t_callback_data(arg1,arg2,arg3,arg4,arg5,arg6) __ao2_callback_data_debug((arg1), (arg2), (arg3), (arg4), (arg5), (arg6), __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \
#define ao2_callback_data(arg1,arg2,arg3,arg4,arg5) __ao2_callback_data_debug((arg1), (arg2), (arg3), (arg4), (arg5), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) __ao2_callback_data_debug((container), (flags), (cb_fn), (arg), (data), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_callback_data(container, flags, cb_fn, arg, data) \
__ao2_callback_data_debug((container), (flags), (cb_fn), (arg), (data), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else #else
#define ao2_t_callback_data(arg1,arg2,arg3,arg4,arg5,arg6) __ao2_callback_data((arg1), (arg2), (arg3), (arg4), (arg5)) #define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \
#define ao2_callback_data(arg1,arg2,arg3,arg4,arg5) __ao2_callback_data((arg1), (arg2), (arg3), (arg4), (arg5)) __ao2_callback_data((container), (flags), (cb_fn), (arg), (data))
#define ao2_callback_data(container, flags, cb_fn, arg, data) \
__ao2_callback_data((container), (flags), (cb_fn), (arg), (data))
#endif #endif
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, ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, char *file,
char *file, int line, const char *funcname); int line, const char *funcname);
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);
@@ -967,18 +1006,22 @@ void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
*/ */
#ifdef REF_DEBUG #ifdef REF_DEBUG
#define ao2_t_find(arg1,arg2,arg3,arg4) __ao2_find_debug((arg1), (arg2), (arg3), (arg4), __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_find(container, arg, flags, tag) \
#define ao2_find(arg1,arg2,arg3) __ao2_find_debug((arg1), (arg2), (arg3), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) __ao2_find_debug((container), (arg), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_find(container, arg, flags) \
__ao2_find_debug((container), (arg), (flags), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else #else
#define ao2_t_find(arg1,arg2,arg3,arg4) __ao2_find((arg1), (arg2), (arg3)) #define ao2_t_find(container, arg, flags, tag) \
#define ao2_find(arg1,arg2,arg3) __ao2_find((arg1), (arg2), (arg3)) __ao2_find((container), (arg), (flags))
#define ao2_find(container, arg, flags) \
__ao2_find((container), (arg), (flags))
#endif #endif
void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
char *file, int line, const char *funcname); const char *tag, char *file, int line, const char *funcname);
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
@@ -1129,13 +1172,13 @@ void ao2_iterator_destroy(struct ao2_iterator *i);
#ifdef REF_DEBUG #ifdef REF_DEBUG
#define ao2_t_iterator_next(arg1, arg2) __ao2_iterator_next_debug((arg1), (arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_t_iterator_next(iter, tag) __ao2_iterator_next_debug((iter), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_iterator_next(arg1) __ao2_iterator_next_debug((arg1), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #define ao2_iterator_next(iter) __ao2_iterator_next_debug((iter), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else #else
#define ao2_t_iterator_next(arg1, arg2) __ao2_iterator_next((arg1)) #define ao2_t_iterator_next(iter, tag) __ao2_iterator_next((iter))
#define ao2_iterator_next(arg1) __ao2_iterator_next((arg1)) #define ao2_iterator_next(iter) __ao2_iterator_next((iter))
#endif #endif

View File

@@ -426,7 +426,7 @@ static struct ao2_container *internal_ao2_container_alloc(struct ao2_container *
return c; return c;
} }
struct ao2_container *__ao2_container_alloc_debug(const unsigned int n_buckets, ao2_hash_fn *hash_fn, struct ao2_container *__ao2_container_alloc_debug(unsigned int n_buckets, ao2_hash_fn *hash_fn,
ao2_callback_fn *cmp_fn, const char *tag, char *file, int line, ao2_callback_fn *cmp_fn, const char *tag, char *file, int line,
const char *funcname, int ref_debug) const char *funcname, int ref_debug)
{ {
@@ -439,7 +439,7 @@ struct ao2_container *__ao2_container_alloc_debug(const unsigned int n_buckets,
return internal_ao2_container_alloc(c, num_buckets, hash_fn, cmp_fn); return internal_ao2_container_alloc(c, num_buckets, hash_fn, cmp_fn);
} }
struct ao2_container *__ao2_container_alloc(const unsigned int n_buckets, ao2_hash_fn *hash_fn, struct ao2_container *__ao2_container_alloc(unsigned int n_buckets, ao2_hash_fn *hash_fn,
ao2_callback_fn *cmp_fn) ao2_callback_fn *cmp_fn)
{ {
/* XXX maybe consistency check on arguments ? */ /* XXX maybe consistency check on arguments ? */
@@ -788,14 +788,14 @@ void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
} }
void *__ao2_callback_data_debug(struct ao2_container *c, void *__ao2_callback_data_debug(struct ao2_container *c,
const enum search_flags flags, enum search_flags flags,
ao2_callback_data_fn *cb_fn, void *arg, void *data, ao2_callback_data_fn *cb_fn, void *arg, void *data,
const char *tag, char *file, int line, const char *funcname) const char *tag, char *file, int line, const char *funcname)
{ {
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, funcname);
} }
void *__ao2_callback_data(struct ao2_container *c, const 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)
{ {
return internal_ao2_callback(c, flags, cb_fn, arg, data, WITH_DATA, NULL, NULL, 0, NULL); return internal_ao2_callback(c, flags, cb_fn, arg, data, WITH_DATA, NULL, NULL, 0, NULL);