diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h index 15655b1f14a31fa3c0c9cba1d3c0b3575a80b9f4..29358e822e3045b0c9b83a7adc27bb52bdb3d8b2 100644 --- a/include/asterisk/astobj2.h +++ b/include/asterisk/astobj2.h @@ -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__) 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); - else + } else { ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); + } return p; } 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); + } return NULL; } #else static struct sip_pvt *dialog_ref(struct sip_pvt *p, const char *tag) { - if (p) + if (p) { ao2_ref(p, 1); - else + } else { ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n"); + } return p; } static struct sip_pvt *dialog_unref(struct sip_pvt *p, const char *tag) { - if (p) + if (p) { ao2_ref(p, -1); + } return NULL; } #endif @@ -332,19 +336,22 @@ Example: *//* Unlink us from the owner (channel) if we have one *//* if (dialog->owner) { - if (lockowner) + if (lockowner) { ast_channel_lock(dialog->owner); + } 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"); - if (lockowner) + if (lockowner) { ast_channel_unlock(dialog->owner); + } } 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 = registry_unref(dialog->registry, "delete dialog->registry"); } - ... + ... dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time"); In the above code, the ao2_t_unlink could end up destroying the dialog @@ -384,14 +391,15 @@ murf 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 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. * + * \details * Allocates a struct astobj2 with sufficient space for the * user-defined structure. * \note @@ -405,24 +413,30 @@ typedef void (*ao2_destructor_fn)(void *); #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_alloc(data_size, destructor_fn) __ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1) +#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_alloc(data_size, destructor_fn) \ + __ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1) #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_alloc(data_size, destructor_fn) __ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) +#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_alloc(data_size, destructor_fn) \ + __ao2_alloc_debug((data_size), (destructor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) #else -#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc((data_size), (destructor_fn)) -#define ao2_alloc(data_size, destructor_fn) __ao2_alloc((data_size), (destructor_fn)) +#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \ + __ao2_alloc((data_size), (destructor_fn)) +#define ao2_alloc(data_size, destructor_fn) \ + __ao2_alloc((data_size), (destructor_fn)) #endif -void *__ao2_alloc_debug(const size_t data_size, ao2_destructor_fn destructor_fn, const char *tag, - 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_debug(size_t data_size, ao2_destructor_fn destructor_fn, const char *tag, + const char *file, int line, const char *funcname, int ref_debug); +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) /*! - * \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. - * \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 * situations, where the locking trace code reports the @@ -518,13 +532,13 @@ Internally, objects are stored in lists, hash tables or other data structures depending on the needs. \note NOTA BENE: at the moment the only container we support is the - hash table and its degenerate form, the list. + hash table and its degenerate form, the list. Operations on container include: - c = \b ao2_container_alloc(size, hash_fn, cmp_fn) - allocate a container with desired size and default compare - and hash function + allocate a container with desired size and default compare + and hash function -The compare function returns an int, which can be 0 for not found, CMP_STOP to stop end a traversal, or CMP_MATCH if they are equal @@ -532,27 +546,31 @@ Operations on container include: takes two argument, the object pointer and a flags field, - \b ao2_find(c, arg, flags) - returns zero or more element matching a given criteria - (specified as arg). 'c' is the container pointer. Flags + returns zero or more elements matching a given criteria + (specified as arg). 'c' is the container pointer. Flags can be: - OBJ_UNLINK - to remove the object, once found, from the container. - OBJ_NODATA - don't return the object if found (no ref count change) - OBJ_MULTIPLE - don't stop at first match - OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table + OBJ_UNLINK - to remove the object, once found, from the container. + OBJ_NODATA - don't return the object if found (no ref count change) + OBJ_MULTIPLE - don't stop at first match + OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table 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) - apply fn(obj, arg) to all objects in the container. - Similar to find. fn() can tell when to stop, and - do anything with the object including unlinking it. - - c is the container; + apply fn(obj, arg) to all objects in the container. + Similar to find. fn() can tell when to stop, and + do anything with the object including unlinking it. + - c is the container; - flags can be - OBJ_UNLINK - to remove the object, once found, from the container. - OBJ_NODATA - don't return the object if found (no ref count change) - OBJ_MULTIPLE - don't stop at first match - OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table + OBJ_UNLINK - to remove the object, once found, from the container. + OBJ_NODATA - don't return the object if found (no ref count change) + OBJ_MULTIPLE - don't stop at first match + OBJ_POINTER - if set, 'arg' is an object pointer, and a hash table search will be done. If not, a traversal is done through 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: (void *obj, void *arg, int flags); obj is an object @@ -563,39 +581,39 @@ Operations on container include: CMP_STOP: stop search, no match CMP_MATCH: This object is matched. - Note that the entire operation is run with the container - locked, so nobody else can change its content while we work on it. - However, we pay this with the fact that doing - anything blocking in the callback keeps the container - blocked. - The mechanism is very flexible because the callback function fn() - can do basically anything e.g. counting, deleting records, etc. - possibly using arg to store the results. + Note that the entire operation is run with the container + locked, so nobody else can change its content while we work on it. + However, we pay this with the fact that doing + anything blocking in the callback keeps the container + blocked. + The mechanism is very flexible because the callback function fn() + can do basically anything e.g. counting, deleting records, etc. + possibly using arg to store the results. - \b iterate on a container - this is done with the following sequence + this is done with the following sequence \code - struct ao2_container *c = ... // our container - struct ao2_iterator i; - void *o; + struct ao2_container *c = ... // our container + struct ao2_iterator i; + void *o; - i = ao2_iterator_init(c, flags); + i = ao2_iterator_init(c, flags); - while ((o = ao2_iterator_next(&i))) { - ... do something on o ... - ao2_ref(o, -1); - } + while ((o = ao2_iterator_next(&i))) { + ... do something on o ... + ao2_ref(o, -1); + } - ao2_iterator_destroy(&i); + ao2_iterator_destroy(&i); \endcode - The difference with the callback is that the control - on how to iterate is left to us. + The difference with the callback is that the control + on how to iterate is left to us. - \b ao2_ref(c, -1) - dropping a reference to a container destroys it, very simple! + dropping a reference to a container destroys it, very simple! Containers are ao2 objects themselves, and this is why their implementation is simple too. @@ -650,11 +668,11 @@ enum search_flags { /*! 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. */ - 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). */ @@ -664,8 +682,8 @@ enum search_flags { * The search function is unaffected (i.e. use the one passed as * argument, or match_by_addr if none specified). */ - OBJ_POINTER = (1 << 3), - /*! + OBJ_POINTER = (1 << 3), + /*! * \brief Continue if a match is not found in the hashed out bucket * * This flag is to be used in combination with OBJ_POINTER. This tells @@ -673,23 +691,25 @@ enum search_flags { * buckets if a match is not found in the starting bucket defined by * the hash value on the argument. */ - OBJ_CONTINUE = (1 << 4), - /*! + OBJ_CONTINUE = (1 << 4), + /*! * \brief By using this flag, the ao2_container being searched will _NOT_ * be locked. Only use this flag if the ao2_container is being protected * by another mechanism other that the internal ao2_lock. */ - OBJ_NOLOCK = (1 << 5), + OBJ_NOLOCK = (1 << 5), /*! * \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 - * to a hash function that is not a full object, but perhaps just - * a string. + * to the container's stored ao2_hash_fn and ao2_find + * 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. */ - OBJ_KEY = (1 << 6), + OBJ_KEY = (1 << 6), }; /*! @@ -705,17 +725,17 @@ typedef int (ao2_hash_fn)(const void *obj, const int flags); /*@{ */ struct ao2_container; -/*! \brief - * Allocate and initialize a container - * with the desired number of buckets. +/*! + * \brief Allocate and initialize a hash container with the desired number of buckets. * + * \details * We allocate space for a struct astobj_container, struct container * and the buckets[] array. * - * \param arg1 Number of buckets for hash - * \param arg2 Pointer to a function computing a hash value. - * \param arg3 Pointer to a compare function used by ao2_find. (NULL to match everything) - * \param arg4 used for debugging. + * \param n_buckets Number of buckets for hash + * \param hash_fn Pointer to a function computing a hash value. + * \param cmp_fn Pointer to a compare function used by ao2_find. (NULL to match everything) + * \param tag used for debugging. * * \return A pointer to a struct container. * @@ -724,27 +744,32 @@ struct ao2_container; #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_container_alloc(arg1,arg2,arg3) __ao2_container_alloc_debug((arg1), (arg2), (arg3), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1) +#define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \ + __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) -#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4), __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) -#define ao2_container_alloc(arg1,arg2,arg3) __ao2_container_alloc_debug((arg1), (arg2), (arg3), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0) +#define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \ + __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 -#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc((arg1), (arg2), (arg3)) -#define ao2_container_alloc(arg1,arg2,arg3) __ao2_container_alloc((arg1), (arg2), (arg3)) +#define ao2_t_container_alloc(n_buckets, hash_fn, cmp_fn, tag) \ + __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 -struct ao2_container *__ao2_container_alloc(const unsigned int n_buckets, - ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn); -struct ao2_container *__ao2_container_alloc_debug(const unsigned int n_buckets, - ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn, - const char *tag, char *file, int line, const char *funcname, - int ref_debug); +struct ao2_container *__ao2_container_alloc(unsigned int n_buckets, ao2_hash_fn *hash_fn, + ao2_callback_fn *cmp_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, const char *funcname, int ref_debug); /*! \brief * 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. * - * \param arg1 the container to operate on. - * \param arg2 the object to be added. - * \param arg3 used for debugging. + * \param container The container to operate on. + * \param obj The object to be added. + * \param tag used for debugging. * * \retval NULL on errors. * \retval newobj on success. @@ -780,17 +805,19 @@ int ao2_container_count(struct ao2_container *c); */ #ifdef REF_DEBUG -#define ao2_t_link(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), 0, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ao2_link(arg1, arg2) __ao2_link_debug((arg1), (arg2), 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(container, obj, tag) __ao2_link_debug((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_link(container, obj) __ao2_link_debug((container), (obj), 0, "", __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 -#define ao2_t_link(arg1, arg2, arg3) __ao2_link((arg1), (arg2), 0) -#define ao2_link(arg1, arg2) __ao2_link((arg1), (arg2), 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(container, obj, tag) __ao2_link((container), (obj), 0) +#define ao2_link(container, obj) __ao2_link((container), (obj), 0) + +#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 @@ -800,9 +827,9 @@ void *__ao2_link(struct ao2_container *c, void *newobj, int flags); /*! * \brief Remove an object from a container * - * \param arg1 the container - * \param arg2 the object to unlink - * \param arg3 tag for debugging + * \param container The container to operate on. + * \param obj The object to unlink. + * \param tag used for debugging. * * \retval NULL, always * @@ -816,17 +843,19 @@ void *__ao2_link(struct ao2_container *c, void *newobj, int flags); */ #ifdef REF_DEBUG -#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink_debug((arg1), (arg2), 0, (arg3), __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ao2_unlink(arg1, arg2) __ao2_unlink_debug((arg1), (arg2), 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(container, obj, tag) __ao2_unlink_debug((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_unlink(container, obj) __ao2_unlink_debug((container), (obj), 0, "", __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 -#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink((arg1), (arg2), 0) -#define ao2_unlink(arg1, arg2) __ao2_unlink((arg1), (arg2), 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(container, obj, tag) __ao2_unlink((container), (obj), 0) +#define ao2_unlink(container, obj) __ao2_unlink((container), (obj), 0) + +#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 @@ -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 flags A set of flags specifying the operation to perform, - partially used by the container code, but also passed to - the callback. - - If OBJ_NODATA is set, ao2_callback will return NULL. No refcounts - of any of the traversed objects will be incremented. - 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, - and you will have no way of knowing which those are, until - the multiple-object-return functionality is implemented. - - If OBJ_POINTER is set, the traversed items will be restricted - to the objects in the bucket that the object key hashes to. + * partially used by the container code, but also passed to + * the callback. + * - If OBJ_NODATA is set, ao2_callback will return NULL. No refcounts + * of any of the traversed objects will be incremented. + * 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, + * and you will have no way of knowing which those are, until + * the multiple-object-return functionality is implemented. + * - If OBJ_POINTER is set, the traversed items will be restricted + * to the objects in the bucket that the object key hashes to. * \param cb_fn A function pointer, that will be called on all - objects, to see if they match. This function returns CMP_MATCH - if the object is matches the criteria; CMP_STOP if the traversal - 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, - but the traversal should continue. This is the function that is applied - to each object traversed. Its arguments are: - (void *obj, void *arg, int flags), where: - obj is an object - arg is the same as arg passed into ao2_callback - flags is the same as flags passed into ao2_callback (flags are - also used by ao2_callback). + * objects, to see if they match. This function returns CMP_MATCH + * if the object is matches the criteria; CMP_STOP if the traversal + * 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, + * but the traversal should continue. This is the function that is applied + * to each object traversed. Its arguments are: + * (void *obj, void *arg, int flags), where: + * obj is an object + * arg is the same as arg passed into ao2_callback + * flags is the same as flags passed into ao2_callback (flags are + * also used by ao2_callback). * \param arg passed to the callback. * \param tag used for debugging. * \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 * CMP_MATCH and CMP_STOP on the desired object. * Other usages are also possible, of course. - + * * This function searches through a container and performs operations * on objects according on flags passed. * XXX describe better @@ -898,13 +927,14 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags); * * The use of flags argument is the follow: * - * OBJ_UNLINK unlinks the object found - * OBJ_NODATA on match, do return an object - * Callbacks use OBJ_NODATA as a default - * functions such as find() do - * OBJ_MULTIPLE return multiple matches - * Default is no. - * OBJ_POINTER the pointer is an object pointer + * OBJ_UNLINK unlinks the object found + * OBJ_NODATA on match, do return an object + * Callbacks use OBJ_NODATA as a default + * functions such as find() do + * OBJ_MULTIPLE return multiple matches + * Default is no. + * 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 * 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 -#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_callback(c,flags,cb_fn,arg) __ao2_callback_debug((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#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_callback(c, flags, cb_fn, arg) \ + __ao2_callback_debug((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #else -#define ao2_t_callback(c,flags,cb_fn,arg,tag) __ao2_callback((c), (flags), (cb_fn), (arg)) -#define ao2_callback(c,flags,cb_fn,arg) __ao2_callback((c), (flags), (cb_fn), (arg)) +#define ao2_t_callback(c, flags, cb_fn, arg, tag) \ + __ao2_callback((c), (flags), (cb_fn), (arg)) +#define ao2_callback(c, flags, cb_fn, arg) \ + __ao2_callback((c), (flags), (cb_fn), (arg)) #endif -void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, - void *arg, const char *tag, char *file, int line, const char *funcname); +void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags, + 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); /*! @} */ @@ -946,39 +981,47 @@ void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callb */ #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_callback_data(arg1,arg2,arg3,arg4,arg5) __ao2_callback_data_debug((arg1), (arg2), (arg3), (arg4), (arg5), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \ + __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 -#define ao2_t_callback_data(arg1,arg2,arg3,arg4,arg5,arg6) __ao2_callback_data((arg1), (arg2), (arg3), (arg4), (arg5)) -#define ao2_callback_data(arg1,arg2,arg3,arg4,arg5) __ao2_callback_data((arg1), (arg2), (arg3), (arg4), (arg5)) +#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \ + __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 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, - char *file, int line, const char *funcname); + ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, char *file, + int line, const char *funcname); 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); /*! ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg) * XXX possibly change order of arguments ? */ #ifdef REF_DEBUG -#define ao2_t_find(arg1,arg2,arg3,arg4) __ao2_find_debug((arg1), (arg2), (arg3), (arg4), __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ao2_find(arg1,arg2,arg3) __ao2_find_debug((arg1), (arg2), (arg3), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define ao2_t_find(container, arg, flags, tag) \ + __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 -#define ao2_t_find(arg1,arg2,arg3,arg4) __ao2_find((arg1), (arg2), (arg3)) -#define ao2_find(arg1,arg2,arg3) __ao2_find((arg1), (arg2), (arg3)) +#define ao2_t_find(container, arg, flags, tag) \ + __ao2_find((container), (arg), (flags)) +#define ao2_find(container, arg, flags) \ + __ao2_find((container), (arg), (flags)) #endif -void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, - char *file, int line, const char *funcname); +void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags, + const char *tag, char *file, int line, const char *funcname); void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags); /*! \brief @@ -1129,13 +1172,13 @@ void ao2_iterator_destroy(struct ao2_iterator *i); #ifdef REF_DEBUG -#define ao2_t_iterator_next(arg1, arg2) __ao2_iterator_next_debug((arg1), (arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define ao2_iterator_next(arg1) __ao2_iterator_next_debug((arg1), "", __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(iter) __ao2_iterator_next_debug((iter), "", __FILE__, __LINE__, __PRETTY_FUNCTION__) #else -#define ao2_t_iterator_next(arg1, arg2) __ao2_iterator_next((arg1)) -#define ao2_iterator_next(arg1) __ao2_iterator_next((arg1)) +#define ao2_t_iterator_next(iter, tag) __ao2_iterator_next((iter)) +#define ao2_iterator_next(iter) __ao2_iterator_next((iter)) #endif diff --git a/main/astobj2.c b/main/astobj2.c index 87b08891957406e04c0802a51fd5f9d7c88b0524..38f3d1b3904f40a64dc15bd40fa4f55fa8ce201a 100644 --- a/main/astobj2.c +++ b/main/astobj2.c @@ -426,7 +426,7 @@ static struct ao2_container *internal_ao2_container_alloc(struct ao2_container * 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, 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); } -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) { /* 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, - const enum search_flags flags, + enum search_flags flags, ao2_callback_data_fn *cb_fn, void *arg, void *data, 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); } -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) { return internal_ao2_callback(c, flags, cb_fn, arg, data, WITH_DATA, NULL, NULL, 0, NULL);