Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
Data Structures | Macros | Typedefs | Enumerations | Functions
astobj2.h File Reference
#include "asterisk/compat.h"
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/inline_api.h"
Include dependency graph for astobj2.h:

Go to the source code of this file.

Data Structures

struct  ao2_global_obj
 
struct  ao2_iterator
 When we need to walk through a container, we use an ao2_iterator to keep track of the current position. More...
 
struct  ao2_weakproxy
 This struct should be opaque, but it's size is needed. More...
 

Macros

#define ao2_alloc_with_lockobj(data_size, destructor_fn, lockobj, tag)    __ao2_alloc_with_lockobj((data_size), (destructor_fn), (lockobj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Allocate and initialize an object with separate locking.
 
#define ao2_callback_data(container, flags, cb_fn, arg, data)    __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_cleanup(obj)   __ao2_cleanup_debug((obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define AO2_FIELD_CMP_FN(stype, fn_suffix, field, key_cmp, partial_key_cmp, transform, argconst)
 
#define AO2_FIELD_HASH_FN(stype, field, hash_fn)
 Creates a hash function for a structure field.
 
#define AO2_FIELD_TRANSFORM_CMP_FN(cmp)   ((cmp) ? 0 : CMP_MATCH)
 
#define AO2_FIELD_TRANSFORM_SORT_FN(cmp)   (cmp)
 
#define ao2_find(container, arg, flags)    __ao2_find((container), (arg), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_global_obj_ref(holder)    __ao2_global_obj_ref(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 Get a reference to the object stored in the global holder.
 
#define ao2_global_obj_release(holder)    __ao2_global_obj_replace_unref(&holder, NULL, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 Release the ao2 object held in the global holder.
 
#define ao2_global_obj_replace(holder, obj)    __ao2_global_obj_replace(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 Replace an ao2 object in the global holder.
 
#define ao2_global_obj_replace_unref(holder, obj)    __ao2_global_obj_replace_unref(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 Replace an ao2 object in the global holder, throwing away any old object.
 
#define AO2_GLOBAL_OBJ_STATIC(name)
 Define a global object holder to be used to hold an ao2 object, statically initialized.
 
#define ao2_iterator_next(iter)    __ao2_iterator_next((iter), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_lock(a)   __ao2_lock(a, AO2_LOCK_REQ_MUTEX, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
 
#define ao2_rdlock(a)   __ao2_lock(a, AO2_LOCK_REQ_RDLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
 
#define AO2_STRING_FIELD_CASE_CMP_FN(stype, field)    AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_CMP_FN,)
 
#define AO2_STRING_FIELD_CASE_HASH_FN(stype, field)    AO2_FIELD_HASH_FN(stype, field, ast_str_case_hash)
 
#define AO2_STRING_FIELD_CASE_SORT_FN(stype, field)    AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_SORT_FN, const)
 
#define AO2_STRING_FIELD_CMP_FN(stype, field)    AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_CMP_FN,)
 Creates a compare function for a structure string field.
 
#define AO2_STRING_FIELD_HASH_FN(stype, field)    AO2_FIELD_HASH_FN(stype, field, ast_str_hash)
 Creates a hash function for a structure string field.
 
#define AO2_STRING_FIELD_SORT_FN(stype, field)    AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_SORT_FN, const)
 Creates a sort function for a structure string field.
 
#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag)    __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 ao2_callback_data() is a generic function that applies cb_fn() to all objects in a container. It is functionally identical to ao2_callback() except that instead of taking an ao2_callback_fn *, it takes an ao2_callback_data_fn *, and allows the caller to pass in arbitrary data.
 
#define ao2_t_cleanup(obj, tag)   __ao2_cleanup_debug((obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_find(container, arg, flags, tag)    __ao2_find((container), (arg), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_global_obj_ref(holder, tag)    __ao2_global_obj_ref(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
#define ao2_t_global_obj_release(holder, tag)    __ao2_global_obj_replace_unref(&holder, NULL, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
#define ao2_t_global_obj_replace(holder, obj, tag)    __ao2_global_obj_replace(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
#define ao2_t_global_obj_replace_unref(holder, obj, tag)    __ao2_global_obj_replace_unref(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
#define ao2_t_iterator_next(iter, tag)    __ao2_iterator_next((iter), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_trylock(a)   __ao2_trylock(a, AO2_LOCK_REQ_MUTEX, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
 
#define ao2_tryrdlock(a)   __ao2_trylock(a, AO2_LOCK_REQ_RDLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
 
#define ao2_trywrlock(a)   __ao2_trylock(a, AO2_LOCK_REQ_WRLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
 
#define ao2_unlock(a)   __ao2_unlock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
 
#define ao2_weakproxy_find(c, arg, flags, tag)    __ao2_weakproxy_find(c, arg, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.
 
#define ao2_wrlock(a)   __ao2_lock(a, AO2_LOCK_REQ_WRLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
 
#define OBJ_KEY   OBJ_SEARCH_KEY
 
#define OBJ_PARTIAL_KEY   OBJ_SEARCH_PARTIAL_KEY
 
#define OBJ_POINTER   OBJ_SEARCH_OBJECT
 

Typedefs

typedef int() ao2_callback_data_fn(void *obj, void *arg, void *data, int flags)
 Type of a generic callback function.
 
typedef int() ao2_callback_fn(void *obj, void *arg, int flags)
 Type of a generic callback function.
 
typedef void(* ao2_destructor_fn) (void *vdoomed)
 Typedef for an object destructor.
 
typedef int() ao2_hash_fn(const void *obj, int flags)
 
typedef int() ao2_sort_fn(const void *obj_left, const void *obj_right, int flags)
 Type of generic container sort function.
 

Enumerations

enum  _cb_results { CMP_MATCH = 0x1 , CMP_STOP = 0x2 }
 A callback function will return a combination of CMP_MATCH and CMP_STOP. The latter will terminate the search in a container. More...
 
enum  ao2_alloc_opts {
  AO2_ALLOC_OPT_LOCK_MUTEX = (0 << 0) , AO2_ALLOC_OPT_LOCK_RWLOCK = (1 << 0) , AO2_ALLOC_OPT_LOCK_NOLOCK = (2 << 0) , AO2_ALLOC_OPT_LOCK_MASK = (3 << 0) ,
  AO2_ALLOC_OPT_LOCK_OBJ = AO2_ALLOC_OPT_LOCK_MASK , AO2_ALLOC_OPT_NO_REF_DEBUG = (1 << 2)
}
 Options available when allocating an ao2 object. More...
 
enum  ao2_container_opts {
  AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN = (1 << 0) , AO2_CONTAINER_ALLOC_OPT_DUPS_MASK = (3 << 1) , AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW = (0 << 1) , AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT = (1 << 1) ,
  AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT = (2 << 1) , AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE = (3 << 1)
}
 Options available when allocating an ao2 container object. More...
 
enum  ao2_iterator_flags { AO2_ITERATOR_DONTLOCK = (1 << 0) , AO2_ITERATOR_MALLOCD = (1 << 1) , AO2_ITERATOR_UNLINK = (1 << 2) , AO2_ITERATOR_DESCENDING = (1 << 3) }
 
enum  ao2_lock_req { AO2_LOCK_REQ_MUTEX , AO2_LOCK_REQ_RDLOCK , AO2_LOCK_REQ_WRLOCK }
 Which lock to request. More...
 
enum  search_flags {
  OBJ_UNLINK = (1 << 0) , OBJ_NODATA = (1 << 1) , OBJ_MULTIPLE = (1 << 2) , OBJ_NOLOCK = (1 << 4) ,
  OBJ_SEARCH_MASK = (0x07 << 5) , OBJ_SEARCH_NONE = (0 << 5) , OBJ_SEARCH_OBJECT = (1 << 5) , OBJ_SEARCH_KEY = (2 << 5) ,
  OBJ_SEARCH_PARTIAL_KEY = (4 << 5) , OBJ_ORDER_MASK = (0x03 << 8) , OBJ_ORDER_ASCENDING = (0 << 8) , OBJ_ORDER_DESCENDING = (1 << 8) ,
  OBJ_ORDER_PRE = (2 << 8) , OBJ_ORDER_POST = (3 << 8)
}
 Flags passed to ao2_callback_fn(), ao2_hash_fn(), and ao2_sort_fn() to modify behaviour. More...
 

Functions

void * __ao2_alloc_with_lockobj (size_t data_size, ao2_destructor_fn destructor_fn, void *lockobj, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
void * __ao2_callback_data (struct ao2_container *c, enum search_flags flags, ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file, int line, const char *func)
 
void __ao2_cleanup (void *obj)
 
void __ao2_cleanup_debug (void *obj, const char *tag, const char *file, int line, const char *function)
 
void * __ao2_find (struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
 
void * __ao2_global_obj_ref (struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result
 
void * __ao2_global_obj_replace (struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result
 
int __ao2_global_obj_replace_unref (struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)
 
void * __ao2_iterator_next (struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
int __ao2_lock (void *a, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
 Lock an object.
 
int __ao2_trylock (void *a, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
 Try locking– (don't block if fail)
 
int __ao2_unlock (void *a, const char *file, const char *func, int line, const char *var)
 Unlock an object.
 
void * __ao2_weakproxy_find (struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
 
void ao2_iterator_cleanup (struct ao2_iterator *iter)
 
int ao2_iterator_count (struct ao2_iterator *iter)
 Get a count of the iterated container objects.
 
void ao2_iterator_destroy (struct ao2_iterator *iter)
 Destroy a container iterator.
 
struct ao2_iterator ao2_iterator_init (struct ao2_container *c, int flags) attribute_warn_unused_result
 Create an iterator for a container.
 
void ao2_iterator_restart (struct ao2_iterator *iter)
 Restart an iteration.
 
int ao2_match_by_addr (void *obj, void *arg, int flags)
 A common ao2_callback is one that matches by address.
 
void * ao2_object_get_lockaddr (void *obj)
 Return the mutex lock address of an object.
 
int ao2_ref_and_lock (void *obj)
 Increment reference count on an object and lock it.
 
int ao2_unlock_and_unref (void *obj)
 Unlock an object and decrement its reference count.
 
void * __ao2_alloc (size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
#define ao2_alloc(data_size, destructor_fn)    __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_alloc_options(data_size, destructor_fn, options)    __ao2_alloc((data_size), (destructor_fn), (options), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)    __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)    __ao2_alloc((data_size), (destructor_fn), (options), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Allocate and initialize an object.
 
int __ao2_ref (void *o, int delta, const char *tag, const char *file, int line, const char *func)
 
#define ao2_bump(obj)    ao2_t_bump((obj), NULL)
 Bump refcount on an AO2 object by one, returning the object.
 
unsigned int ao2_options_get (void *obj)
 Retrieve the ao2 options used to create the object.
 
#define ao2_ref(o, delta)   __ao2_ref((o), (delta), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Reference/unreference an object and return the old refcount.
 
#define ao2_replace(dst, src)    ao2_t_replace((dst), (src), NULL)
 Replace one object reference with another cleaning up the original.
 
#define ao2_t_bump(obj, tag)
 
#define ao2_t_ref(o, delta, tag)   __ao2_ref((o), (delta), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_replace(dst, src, tag)
 
void * __ao2_get_weakproxy (void *obj, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
void * __ao2_weakproxy_alloc (size_t data_size, ao2_destructor_fn destructor_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
void * __ao2_weakproxy_get_object (void *weakproxy, int flags, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
int __ao2_weakproxy_ref_object (void *weakproxy, int delta, int flags, const char *tag, const char *file, int line, const char *func)
 
int __ao2_weakproxy_set_object (void *weakproxy, void *obj, int flags, const char *tag, const char *file, int line, const char *func)
 
#define ao2_get_weakproxy(obj)    __ao2_get_weakproxy(obj, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Get the weakproxy attached to obj.
 
#define ao2_t_get_weakproxy(obj, tag)    __ao2_get_weakproxy(obj, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_weakproxy_alloc(data_size, destructor_fn, tag)    __ao2_weakproxy_alloc(data_size, destructor_fn, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_weakproxy_get_object(weakproxy, flags, tag)    __ao2_weakproxy_get_object(weakproxy, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_weakproxy_ref_object(weakproxy, delta, flags, tag)
 
#define ao2_t_weakproxy_set_object(weakproxy, obj, flags, tag)    __ao2_weakproxy_set_object(weakproxy, obj, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define AO2_WEAKPROXY()   struct ao2_weakproxy __weakproxy##__LINE__
 Macro which must be used at the beginning of weakproxy capable objects.
 
#define ao2_weakproxy_alloc(data_size, destructor_fn)    __ao2_weakproxy_alloc(data_size, destructor_fn, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Allocate an ao2_weakproxy object.
 
#define ao2_weakproxy_get_object(weakproxy, flags)    __ao2_weakproxy_get_object(weakproxy, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Get the object associated with weakproxy.
 
typedef void(* ao2_weakproxy_notification_cb) (void *weakproxy, void *data)
 
#define ao2_weakproxy_ref_object(weakproxy, delta, flags)    ao2_t_weakproxy_ref_object(weakproxy, delta, flags, NULL)
 Run ao2_t_ref on the object associated with weakproxy.
 
#define ao2_weakproxy_set_object(weakproxy, obj, flags)    __ao2_weakproxy_set_object(weakproxy, obj, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Associate weakproxy with obj.
 
int ao2_weakproxy_subscribe (void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
 Request notification when weakproxy points to NULL.
 
int ao2_weakproxy_unsubscribe (void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
 Remove notification of real object destruction.
 

Object Containers

Here start declarations of containers.

struct ao2_container__ao2_container_alloc_hash (unsigned int ao2_options, unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
struct ao2_container__ao2_container_alloc_list (unsigned int ao2_options, unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
struct ao2_container__ao2_container_alloc_rbtree (unsigned int ao2_options, unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
struct ao2_container__ao2_container_clone (struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
 
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)    __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Allocate and initialize a hash container with the desired number of buckets.
 
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)    __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Allocate and initialize a list container.
 
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)    __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Allocate and initialize a red-black tree container.
 
int ao2_container_check (struct ao2_container *self, enum search_flags flags)
 Perform an integrity check on the specified container.
 
#define ao2_container_clone(orig, flags)    __ao2_container_clone(orig, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Create a clone/copy of the given container.
 
int ao2_container_count (struct ao2_container *c)
 Returns the number of elements in a container.
 
void ao2_container_dump (struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj)
 Display contents of the specified container.
 
int ao2_container_dup (struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
 Copy all object references in the src container into the dest container.
 
int ao2_container_dup_weakproxy_objs (struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
 Copy object references associated with src container weakproxies into the dest container.
 
int ao2_container_register (const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
 Register a container for CLI stats and integrity check.
 
void ao2_container_stats (struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt)
 Display statistics of the specified container.
 
void ao2_container_unregister (const char *name)
 Unregister a container for CLI stats and integrity check.
 
typedef void() ao2_prnt_fn(void *where, const char *fmt,...)
 Print output.
 
typedef void() ao2_prnt_obj_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)
 Print object key.
 
#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag)    __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn, tag)    __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn, tag)    __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_container_clone(orig, flags, tag)    __ao2_container_clone(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 

Object Management

Here we have functions to manage objects.

We can use the functions below on any kind of object defined by the user.

int __ao2_link (struct ao2_container *c, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func)
 
void * __ao2_unlink (struct ao2_container *c, void *obj, int flags, const char *tag, const char *file, int line, const char *func)
 
#define ao2_link(container, obj)    __ao2_link((container), (obj), 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Add an object to a container.
 
#define ao2_link_flags(container, obj, flags)    __ao2_link((container), (obj), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Add an object to a container.
 
#define ao2_t_link(container, obj, tag)    __ao2_link((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_link_flags(container, obj, flags, tag)    __ao2_link((container), (obj), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_unlink(container, obj, tag)    __ao2_unlink((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_t_unlink_flags(container, obj, flags, tag)    __ao2_unlink((container), (obj), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
#define ao2_unlink(container, obj)    __ao2_unlink((container), (obj), 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Remove an object from a container.
 
#define ao2_unlink_flags(container, obj, flags)    __ao2_unlink((container), (obj), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 Remove an object from a container.
 
void * __ao2_callback (struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line, const char *func)
 
#define ao2_callback(c, flags, cb_fn, arg)    __ao2_callback((c), (flags), (cb_fn), (arg), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
 
#define ao2_t_callback(c, flags, cb_fn, arg, tag)    __ao2_callback((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 

Detailed Description

Object Model implementing objects and containers.

Definition in file astobj2.h.

Macro Definition Documentation

◆ ao2_alloc

#define ao2_alloc (   data_size,
  destructor_fn 
)     __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
Examples
app_skel.c.

Definition at line 409 of file astobj2.h.

483 { \
484 typeof(obj) __obj_ ## __LINE__ = (obj); \
485 if (__obj_ ## __LINE__) { \
486 ao2_t_ref(__obj_ ## __LINE__, +1, (tag)); \
487 } \
488 __obj_ ## __LINE__; \
489 })
490
491int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func);
492
493/*!
494 * \since 12.4.0
495 * \brief Replace one object reference with another cleaning up the original.
496 *
497 * \param dst Pointer to the object that will be cleaned up.
498 * \param src Pointer to the object replacing it.
499 */
500#define ao2_replace(dst, src) \
501 ao2_t_replace((dst), (src), NULL)
502
503#define ao2_t_replace(dst, src, tag) \
504 {\
505 typeof(dst) *__dst_ ## __LINE__ = &dst; \
506 typeof(src) __src_ ## __LINE__ = src; \
507 if (__src_ ## __LINE__ != *__dst_ ## __LINE__) { \
508 if (__src_ ## __LINE__) {\
509 ao2_t_ref(__src_ ## __LINE__, +1, (tag)); \
510 } \
511 if (*__dst_ ## __LINE__) {\
512 ao2_t_ref(*__dst_ ## __LINE__, -1, (tag)); \
513 } \
514 *__dst_ ## __LINE__ = __src_ ## __LINE__; \
515 } \
516 }
517
518/*! @} */
519
520/*! \brief ao2_weakproxy
521 *
522 * @{
523 */
525typedef void (*ao2_weakproxy_notification_cb)(void *weakproxy, void *data);
526
527/*! \brief This struct should be opaque, but it's size is needed. */
528struct ao2_weakproxy {
530};
531
532/*! \brief Macro which must be used at the beginning of weakproxy capable objects.
533 *
534 * \note The primary purpose of user defined fields on weakproxy objects is to hold
535 * immutable container keys for the real object.
536 */
537#define AO2_WEAKPROXY() struct ao2_weakproxy __weakproxy##__LINE__
538
539/*!
540 * \since 14.0.0
541 * \brief Allocate an ao2_weakproxy object
542 *
543 * \param data_size The sizeof() of the user-defined structure.
544 * \param destructor_fn The destructor function (can be NULL)
545 *
546 * \note "struct ao2_weakproxy" must be the first field of any object.
547 * This can be done by using AO2_WEAKPROXY to declare your structure.
548 */
549#define ao2_weakproxy_alloc(data_size, destructor_fn) \
550 __ao2_weakproxy_alloc(data_size, destructor_fn, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
551
552#define ao2_t_weakproxy_alloc(data_size, destructor_fn, tag) \
553 __ao2_weakproxy_alloc(data_size, destructor_fn, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
554
555void *__ao2_weakproxy_alloc(size_t data_size, ao2_destructor_fn destructor_fn,
556 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
557
558/*!
559 * \since 14.0.0
560 * \brief Associate weakproxy with obj.
561 *
562 * \param weakproxy An object created by ao2_weakproxy_alloc.
563 * \param obj An ao2 object not created by ao2_weakproxy_alloc.
564 * \param flags OBJ_NOLOCK to avoid locking weakproxy.
565 *
566 * \retval 0 Success
567 * \retval -1 Failure
568 *
569 * \note obj must be newly created, this procedure is not thread safe
570 * if any other code can reach obj before this procedure ends.
571 *
572 * \note weakproxy may be previously existing, but must not currently
573 * have an object set.
574 *
575 * \note The only way to unset an object is for it to be destroyed.
576 * Any call to this function while an object is already set will fail.
577 */
578#define ao2_weakproxy_set_object(weakproxy, obj, flags) \
579 __ao2_weakproxy_set_object(weakproxy, obj, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
580
581#define ao2_t_weakproxy_set_object(weakproxy, obj, flags, tag) \
582 __ao2_weakproxy_set_object(weakproxy, obj, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
583
584int __ao2_weakproxy_set_object(void *weakproxy, void *obj, int flags,
585 const char *tag, const char *file, int line, const char *func);
586
587/*!
588 * \since 14.0.0
589 * \brief Run ao2_t_ref on the object associated with weakproxy.
590 *
591 * \param weakproxy The weakproxy to read from.
592 * \param delta Value to add to the reference counter.
593 * \param flags OBJ_NOLOCK to avoid locking weakproxy.
594 *
595 * \retval -2 weakproxy is not a valid ao2_weakproxy.
596 * \retval -1 weakproxy has no associated object.
597 *
598 * \return The value of the reference counter before the operation.
599 */
600#define ao2_weakproxy_ref_object(weakproxy, delta, flags) \
601 ao2_t_weakproxy_ref_object(weakproxy, delta, flags, NULL)
602
603#define ao2_t_weakproxy_ref_object(weakproxy, delta, flags, tag) \
604 __ao2_weakproxy_ref_object(weakproxy, delta, flags, \
605 tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
606
607int __ao2_weakproxy_ref_object(void *weakproxy, int delta, int flags,
608 const char *tag, const char *file, int line, const char *func);
609
610/*!
611 * \since 14.0.0
612 * \brief Get the object associated with weakproxy.
613 *
614 * \param weakproxy The weakproxy to read from.
615 * \param flags OBJ_NOLOCK to avoid locking weakproxy.
616 *
617 * \return A reference to the object previously set by ao2_weakproxy_set_object.
618 * \retval NULL Either no object was set or the previously set object has been freed.
619 */
620#define ao2_weakproxy_get_object(weakproxy, flags) \
621 __ao2_weakproxy_get_object(weakproxy, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
622
623#define ao2_t_weakproxy_get_object(weakproxy, flags, tag) \
624 __ao2_weakproxy_get_object(weakproxy, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
625
626void *__ao2_weakproxy_get_object(void *weakproxy, int flags,
627 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
628
629/*!
630 * \since 14.0.0
631 * \brief Request notification when weakproxy points to NULL.
632 *
633 * \param weakproxy The weak object
634 * \param cb Procedure to call when no real object is associated
635 * \param data Passed to cb
636 * \param flags OBJ_NOLOCK to avoid locking weakproxy.
637 *
638 * \retval 0 Success
639 * \retval -1 Failure
640 *
641 * \note Callbacks are run in the reverse order of subscriptions.
642 *
643 * \note This procedure will allow the same cb / data pair to be added to
644 * the same weakproxy multiple times.
645 *
646 * \note It is the caller's responsibility to ensure that *data is valid
647 * until after cb() is run or ao2_weakproxy_unsubscribe is called.
648 *
649 * \note If the weakproxy currently points to NULL the callback will be run immediately,
650 * without being added to the subscriber list.
651 */
652int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags);
653
654/*!
655 * \since 14.0.0
656 * \brief Remove notification of real object destruction.
657 *
658 * \param weakproxy The weak object
659 * \param cb Callback to remove from destroy notification list
660 * \param data Data pointer to match
661 * \param flags OBJ_NOLOCK to avoid locking weakproxy.
662 * OBJ_MULTIPLE to remove all copies of the same cb / data pair.
663 *
664 * \return The number of subscriptions removed.
665 * \retval 0 cb / data pair not found, nothing removed.
666 * \retval -1 Failure due to invalid parameters.
667 *
668 * \note Unless flags includes OBJ_MULTIPLE, this will only remove a single copy
669 * of the cb / data pair. If it was subscribed multiple times it must be
670 * unsubscribed as many times. The OBJ_MULTIPLE flag can be used to remove
671 * matching subscriptions.
672 *
673 * \note When it's time to run callbacks they are copied to a temporary list so the
674 * weakproxy can be unlocked before running. That means it's possible for
675 * this function to find nothing before the callback is run in another thread.
676 */
677int ao2_weakproxy_unsubscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags);
678
679/*!
680 * \since 14.0.0
681 * \brief Get the weakproxy attached to obj
682 *
683 * \param obj The object to retrieve a weakproxy from
684 *
685 * \return The weakproxy object
686 */
687#define ao2_get_weakproxy(obj) \
688 __ao2_get_weakproxy(obj, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
689
690#define ao2_t_get_weakproxy(obj, tag) \
691 __ao2_get_weakproxy(obj, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
692
693void *__ao2_get_weakproxy(void *obj,
694 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
695/*! @} */
696
697
698/*! \brief Which lock to request. */
699enum ao2_lock_req {
700 /*! Request the mutex lock be acquired. */
702 /*! Request the read lock be acquired. */
704 /*! Request the write lock be acquired. */
706};
707
708/*! \brief
709 * Lock an object.
710 *
711 * \param a A pointer to the object we want to lock.
712 * \param lock_how, file, func, line, var
713 * \return 0 on success, other values on error.
714 */
715int __ao2_lock(void *a, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var);
716#define ao2_lock(a) __ao2_lock(a, AO2_LOCK_REQ_MUTEX, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
717#define ao2_rdlock(a) __ao2_lock(a, AO2_LOCK_REQ_RDLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
718#define ao2_wrlock(a) __ao2_lock(a, AO2_LOCK_REQ_WRLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
719
720/*! \brief
721 * Unlock an object.
722 *
723 * \param a A pointer to the object we want unlock.
724 * \param file, func, line, var
725 * \return 0 on success, other values on error.
726 */
727int __ao2_unlock(void *a, const char *file, const char *func, int line, const char *var);
728#define ao2_unlock(a) __ao2_unlock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
729
730/*! \brief
731 * Try locking-- (don't block if fail)
732 *
733 * \param a A pointer to the object we want to lock.
734 * \param lock_how, file, func, line, var
735 * \return 0 on success, other values on error.
736 */
737int __ao2_trylock(void *a, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var);
738#define ao2_trylock(a) __ao2_trylock(a, AO2_LOCK_REQ_MUTEX, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
739#define ao2_tryrdlock(a) __ao2_trylock(a, AO2_LOCK_REQ_RDLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
740#define ao2_trywrlock(a) __ao2_trylock(a, AO2_LOCK_REQ_WRLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
741
742/*!
743 * \brief Return the mutex lock address of an object
744 *
745 * \param[in] obj A pointer to the object we want.
746 * \return the address of the mutex lock, else NULL.
747 *
748 * This function comes in handy mainly for debugging locking
749 * situations, where the locking trace code reports the
750 * lock address, this allows you to correlate against
751 * object address, to match objects to reported locks.
752 *
753 * \warning AO2 lock objects do not include tracking fields when
754 * DEBUG_THREADS is not enabled.
755 *
756 * \since 1.6.1
757 */
758void *ao2_object_get_lockaddr(void *obj);
759
760
761/*!
762 * \brief Increment reference count on an object and lock it
763 * \since 13.9.0
764 *
765 * \param[in] obj A pointer to the ao2 object
766 * \retval 0 The object is not an ao2 object or wasn't locked successfully
767 * \retval 1 The object's reference count was incremented and was locked
768 */
770int ao2_ref_and_lock(void *obj),
771{
772 ao2_ref(obj, +1);
773 if (ao2_lock(obj)) {
774 ao2_ref(obj, -1);
775 return 0;
776 }
777 return 1;
778}
779)
780
781/*!
782 * \brief Unlock an object and decrement its reference count
783 * \since 13.9.0
784 *
785 * \param[in] obj A pointer to the ao2 object
786 * \retval 0 The object is not an ao2 object or wasn't unlocked successfully
787 * \retval 1 The object was unlocked and it's reference count was decremented
788 */
790int ao2_unlock_and_unref(void *obj),
791{
792 if (ao2_unlock(obj)) {
793 return 0;
794 }
795 ao2_ref(obj, -1);
796
797 return 1;
798}
799)
800
801/*! Global ao2 object holder structure. */
802struct ao2_global_obj {
803 /*! Access lock to the held ao2 object. */
805 /*! Global ao2 object. */
806 void *obj;
807};
808
809/*!
810 * \brief Define a global object holder to be used to hold an ao2 object, statically initialized.
811 * \since 11.0
812 *
813 * \param name This will be the name of the object holder.
814 *
815 * \details
816 * This macro creates a global object holder that can be used to
817 * hold an ao2 object accessible using the API. The structure is
818 * allocated and initialized to be empty.
819 *
820 * Example usage:
821 * \code
822 * static AO2_GLOBAL_OBJ_STATIC(global_cfg);
823 * \endcode
824 *
825 * This defines global_cfg, intended to hold an ao2 object
826 * accessible using an API.
827 */
828#ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
829#define AO2_GLOBAL_OBJ_STATIC(name) \
830 struct ao2_global_obj name; \
831 static void __attribute__((constructor)) __init_##name(void) \
832 { \
833 ast_rwlock_init(&name.lock); \
834 name.obj = NULL; \
835 } \
836 static void __attribute__((destructor)) __fini_##name(void) \
837 { \
838 if (name.obj) { \
839 ao2_ref(name.obj, -1); \
840 name.obj = NULL; \
841 } \
842 ast_rwlock_destroy(&name.lock); \
843 } \
844 struct __dummy_##name
845#else
846#define AO2_GLOBAL_OBJ_STATIC(name) \
847 struct ao2_global_obj name = { \
848 .lock = AST_RWLOCK_INIT_VALUE, \
849 }
850#endif
851
852/*!
853 * \brief Release the ao2 object held in the global holder.
854 * \since 11.0
855 *
856 * \param holder Global ao2 object holder.
857 */
858#define ao2_global_obj_release(holder) \
859 __ao2_global_obj_replace_unref(&holder, NULL, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
860#define ao2_t_global_obj_release(holder, tag) \
861 __ao2_global_obj_replace_unref(&holder, NULL, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
862
863/*!
864 * \brief Replace an ao2 object in the global holder.
865 * \since 11.0
866 *
867 * \param holder Global ao2 object holder.
868 * \param obj Object to put into the holder. Can be NULL.
869 *
870 * \note This function automatically increases the reference
871 * count to account for the reference that the global holder now
872 * holds to the object.
873 *
874 * \return Reference to previous global ao2 object stored.
875 * \retval NULL if no object available.
876 */
877#define ao2_global_obj_replace(holder, obj) \
878 __ao2_global_obj_replace(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
879
880#define ao2_t_global_obj_replace(holder, obj, tag) \
881 __ao2_global_obj_replace(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
882
883void *__ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result;
884
885/*!
886 * \brief Replace an ao2 object in the global holder, throwing away any old object.
887 * \since 11.0
888 *
889 * \param holder Global ao2 object holder.
890 * \param obj Object to put into the holder. Can be NULL.
891 *
892 * \note This function automatically increases the reference
893 * count to account for the reference that the global holder now
894 * holds to the object. It also decreases the reference count
895 * of any object being replaced.
896 *
897 * \retval 0 The global object was previously empty
898 * \retval 1 The global object was not previously empty
899 */
900#define ao2_global_obj_replace_unref(holder, obj) \
901 __ao2_global_obj_replace_unref(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
902
903#define ao2_t_global_obj_replace_unref(holder, obj, tag) \
904 __ao2_global_obj_replace_unref(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
905
906int __ao2_global_obj_replace_unref(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name);
907
908/*!
909 * \brief Get a reference to the object stored in the global holder.
910 * \since 11.0
911 *
912 * \param holder Global ao2 object holder.
913 *
914 * \return Reference to current ao2 object stored in the holder.
915 * \retval NULL if no object available.
916 */
917#define ao2_global_obj_ref(holder) \
918 __ao2_global_obj_ref(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
919
920#define ao2_t_global_obj_ref(holder, tag) \
921 __ao2_global_obj_ref(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
922
923void *__ao2_global_obj_ref(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result;
924
925
926/*!
927 \page AstObj2_Containers AstObj2 Containers
928
929Containers are data structures meant to store several objects,
930and perform various operations on them.
931Internally, objects are stored in lists, hash tables or other
932data structures depending on the needs.
933
934Operations on container include:
935
936 - \b ao2_find(c, arg, flags)
937 returns zero or more elements matching a given criteria
938 (specified as arg). 'c' is the container pointer. Flags
939 can be:
940 OBJ_UNLINK - to remove the object, once found, from the container.
941 OBJ_NODATA - don't return the object if found (no ref count change)
942 OBJ_MULTIPLE - don't stop at first match
943 OBJ_SEARCH_OBJECT - if set, 'arg' is an object pointer, and a hash table
944 search will be done. If not, a traversal is done.
945 OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
946 Similar to OBJ_SEARCH_OBJECT and mutually exclusive.
947 OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
948 Similar to OBJ_SEARCH_KEY and mutually exclusive.
949
950 - \b ao2_callback(c, flags, fn, arg)
951 apply fn(obj, arg) to all objects in the container.
952 Similar to find. fn() can tell when to stop, and
953 do anything with the object including unlinking it.
954 - c is the container;
955 - flags can be
956 OBJ_UNLINK - to remove the object, once found, from the container.
957 OBJ_NODATA - don't return the object if found (no ref count change)
958 OBJ_MULTIPLE - don't stop at first match
959 OBJ_SEARCH_OBJECT - if set, 'arg' is an object pointer, and a hash table
960 search will be done. If not, a traversal is done through
961 all the hash table 'buckets'..
962 OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
963 Similar to OBJ_SEARCH_OBJECT and mutually exclusive.
964 OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
965 Similar to OBJ_SEARCH_KEY and mutually exclusive.
966 - fn is a func that returns int, and takes 3 args:
967 (void *obj, void *arg, int flags);
968 obj is an object
969 arg is the same as arg passed into ao2_callback
970 flags is the same as flags passed into ao2_callback
971 fn returns:
972 0: no match, keep going
973 CMP_STOP: stop search, no match
974 CMP_MATCH: This object is matched.
975
976 Note that the entire operation is run with the container
977 locked, so nobody else can change its content while we work on it.
978 However, we pay this with the fact that doing
979 anything blocking in the callback keeps the container
980 blocked.
981 The mechanism is very flexible because the callback function fn()
982 can do basically anything e.g. counting, deleting records, etc.
983 possibly using arg to store the results.
984
985 - \b iterate on a container
986 this is done with the following sequence
987
988\code
989
990 struct ao2_container *c = ... // our container
991 struct ao2_iterator i;
992 void *o;
993
994 i = ao2_iterator_init(c, flags);
995
996 while ((o = ao2_iterator_next(&i))) {
997 ... do something on o ...
998 ao2_ref(o, -1);
999 }
1000
1001 ao2_iterator_destroy(&i);
1002\endcode
1003
1004 The difference with the callback is that the control
1005 on how to iterate is left to us.
1006
1007 - \b ao2_ref(c, -1)
1008 dropping a reference to a container destroys it, very simple!
1009
1010Containers are ao2 objects themselves, and this is why their
1011implementation is simple too.
1012
1013Before declaring containers, we need to declare the types of the
1014arguments passed to the constructor - in turn, this requires
1015to define callback and hash functions and their arguments.
1016
1017- \ref AstObj2
1018- \ref astobj2.h
1019 */
1020
1021/*! \brief
1022 * A callback function will return a combination of CMP_MATCH and CMP_STOP.
1023 * The latter will terminate the search in a container.
1024 */
1025enum _cb_results {
1026 CMP_MATCH = 0x1, /*!< the object matches the request */
1027 CMP_STOP = 0x2, /*!< stop the search now */
1028};
1029
1030/*!
1031 * \brief Flags passed to ao2_callback_fn(), ao2_hash_fn(), and ao2_sort_fn() to modify behaviour.
1032 */
1033enum search_flags {
1034 /*!
1035 * Unlink the object for which the callback function returned
1036 * CMP_MATCH.
1037 */
1038 OBJ_UNLINK = (1 << 0),
1039 /*!
1040 * On match, don't return the object hence do not increase its
1041 * refcount.
1042 */
1043 OBJ_NODATA = (1 << 1),
1044 /*!
1045 * Don't stop at the first match in ao2_callback() unless the
1046 * result of the callback function has the CMP_STOP bit set.
1047 */
1048 OBJ_MULTIPLE = (1 << 2),
1049 /*!
1050 * \brief Assume that the ao2_container is already locked.
1051 *
1052 * \note For ao2_containers that have mutexes, no locking will
1053 * be done.
1054 *
1055 * \note For ao2_containers that have RWLOCKs, the lock will be
1056 * promoted to write mode as needed. The lock will be returned
1057 * to the original locked state.
1058 *
1059 * \note Only use this flag if the ao2_container is manually
1060 * locked already.
1061 */
1062 OBJ_NOLOCK = (1 << 4),
1063
1064 /*!
1065 * \brief Search option field mask.
1066 *
1067 * \todo Eventually OBJ_SEARCH_MASK will shrink to a two bit
1068 * field when the codebase is made to use the search field
1069 * values as a field instead of independent bits.
1070 */
1071 OBJ_SEARCH_MASK = (0x07 << 5),
1072 /*! \brief The arg parameter has no meaning to the astobj2 code. */
1073 OBJ_SEARCH_NONE = (0 << 5),
1074 /*!
1075 * \brief The arg parameter is an object of the same type.
1076 *
1077 * \details
1078 * The arg parameter is an object of the same type as the one
1079 * being searched for, so use the object's ao2_hash_fn and/or
1080 * ao2_sort_fn functions for optimized searching.
1081 *
1082 * \note The supplied ao2_callback_fn is called after the
1083 * container nodes have been filtered by the ao2_hash_fn and/or
1084 * ao2_sort_fn functions.
1085 */
1086 OBJ_SEARCH_OBJECT = (1 << 5),
1087 /*!
1088 * \brief The arg parameter is a search key, but is not an object.
1089 *
1090 * \details
1091 * This can be used when you want to be able to pass custom data
1092 * to the container's stored ao2_hash_fn, ao2_sort_fn, and
1093 * ao2_find ao2_callback_fn functions that is not a full object,
1094 * but perhaps just a string.
1095 *
1096 * \note The supplied ao2_callback_fn is called after the
1097 * container nodes have been filtered by the ao2_hash_fn and/or
1098 * ao2_sort_fn functions.
1099 */
1100 OBJ_SEARCH_KEY = (2 << 5),
1101 /*!
1102 * \brief The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
1103 *
1104 * \details
1105 * The partial key can be used by the ao2_sort_fn to guide the
1106 * search to find a contiguous subset of a sorted container.
1107 * For example, a sorted container holds: "A", "B", "Bert",
1108 * "Beth", "Earnie". Doing a partial key search with "B" will
1109 * find the sorted subset of all held objects starting with "B".
1110 *
1111 * \note The supplied ao2_callback_fn is called after the
1112 * container nodes have been filtered by the ao2_sort_fn
1113 * function.
1114 */
1115 OBJ_SEARCH_PARTIAL_KEY = (4 << 5),
1116
1117 /*! \brief Traverse order option field mask. */
1118 OBJ_ORDER_MASK = (0x03 << 8),
1119 /*! \brief Traverse in ascending order (First to last container object) */
1120 OBJ_ORDER_ASCENDING = (0 << 8),
1121 /*! \brief Traverse in descending order (Last to first container object) */
1122 OBJ_ORDER_DESCENDING = (1 << 8),
1123 /*!
1124 * \brief Traverse in pre-order (Node then children, for tree container)
1125 *
1126 * \note For non-tree containers, it is up to the container type
1127 * to make the best interpretation of the order. For list and
1128 * hash containers, this also means ascending order because a
1129 * binary tree can degenerate into a list.
1130 */
1131 OBJ_ORDER_PRE = (2 << 8),
1132 /*!
1133 * \brief Traverse in post-order (Children then node, for tree container)
1134 *
1135 * \note For non-tree containers, it is up to the container type
1136 * to make the best interpretation of the order. For list and
1137 * hash containers, this also means descending order because a
1138 * binary tree can degenerate into a list.
1139 */
1140 OBJ_ORDER_POST = (3 << 8),
1141};
1142
1143/*
1144 * Deprecated backward compatible flag names.
1145 *
1146 * Note: OBJ_POINTER, OBJ_KEY, and OBJ_PARTIAL_KEY are mutually
1147 * exclusive.
1148 */
1149#define OBJ_POINTER OBJ_SEARCH_OBJECT /*!< Deprecated name */
1150#define OBJ_KEY OBJ_SEARCH_KEY /*!< Deprecated name */
1151#define OBJ_PARTIAL_KEY OBJ_SEARCH_PARTIAL_KEY /*!< Deprecated name */
1152
1153/*!
1154 * \brief Options available when allocating an ao2 container object.
1155 *
1156 * \note Each option is open to some interpretation by the
1157 * container type as long as it makes sense with the option
1158 * name.
1159 */
1160enum ao2_container_opts {
1161 /*!
1162 * \brief Insert objects at the beginning of the container.
1163 * (Otherwise it is the opposite; insert at the end.)
1164 *
1165 * \note If an ao2_sort_fn is provided, the object is inserted
1166 * before any objects with duplicate keys.
1167 *
1168 * \note Hash containers insert the object in the computed hash
1169 * bucket in the indicated manner.
1170 */
1172
1173 /*!
1174 * \brief The ao2 container objects with duplicate keys option field mask.
1175 */
1177 /*!
1178 * \brief Allow objects with duplicate keys in container.
1179 */
1181 /*!
1182 * \brief Reject objects with duplicate keys in container.
1183 *
1184 * \note The container must be sorted. i.e. have an
1185 * ao2_sort_fn.
1186 */
1188 /*!
1189 * \brief Reject duplicate objects in container.
1190 *
1191 * \details Don't link the same object into the container twice.
1192 * However, you can link a different object with the same key.
1193 *
1194 * \note The container must be sorted. i.e. have an
1195 * ao2_sort_fn.
1196 *
1197 * \note It is assumed that the objects are located where the
1198 * search key says they should be located.
1199 */
1201 /*!
1202 * \brief Replace objects with duplicate keys in container.
1203 *
1204 * \details The existing duplicate object is removed and the new
1205 * object takes the old object's place.
1206 *
1207 * \note The container must be sorted. i.e. have an
1208 * ao2_sort_fn.
1209 */
1211};
1212
1213/*!
1214 * \brief Type of a generic callback function
1215 * \param obj pointer to the (user-defined part) of an object.
1216 * \param arg callback argument from ao2_callback()
1217 * \param flags flags from ao2_callback()
1218 * OBJ_SEARCH_OBJECT - if set, 'arg', is an object.
1219 * OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
1220 * OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
1221 *
1222 * The return values are a combination of enum _cb_results.
1223 * Callback functions are used to search or manipulate objects in a container.
1224 */
1225typedef int (ao2_callback_fn)(void *obj, void *arg, int flags);
1226
1227/*! \brief A common ao2_callback is one that matches by address. */
1228int ao2_match_by_addr(void *obj, void *arg, int flags);
1229
1230/*!
1231 * \brief Type of a generic callback function
1232 * \param obj pointer to the (user-defined part) of an object.
1233 * \param arg callback argument from ao2_callback()
1234 * \param data arbitrary data from ao2_callback()
1235 * \param flags flags from ao2_callback()
1236 * OBJ_SEARCH_OBJECT - if set, 'arg', is an object.
1237 * OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object.
1238 * OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.
1239 *
1240 * The return values are a combination of enum _cb_results.
1241 * Callback functions are used to search or manipulate objects in a container.
1242 */
1243typedef int (ao2_callback_data_fn)(void *obj, void *arg, void *data, int flags);
1244
1245/*!
1246 * Type of a generic function to generate a hash value from an object.
1247 *
1248 * \param obj pointer to the (user-defined part) of an object.
1249 * \param flags flags from ao2_callback()
1250 * OBJ_SEARCH_OBJECT - if set, 'obj', is an object.
1251 * OBJ_SEARCH_KEY - if set, 'obj', is a search key item that is not an object.
1252 *
1253 * \note This function must be idempotent.
1254 *
1255 * \return Computed hash value.
1256 */
1257typedef int (ao2_hash_fn)(const void *obj, int flags);
1258
1259/*!
1260 * \brief Type of generic container sort function.
1261 *
1262 * \param obj_left pointer to the (user-defined part) of an object.
1263 * \param obj_right pointer to the (user-defined part) of an object.
1264 * \param flags flags from ao2_callback()
1265 * OBJ_SEARCH_OBJECT - if set, 'obj_right', is an object.
1266 * OBJ_SEARCH_KEY - if set, 'obj_right', is a search key item that is not an object.
1267 * OBJ_SEARCH_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
1268 *
1269 * \note This function must be idempotent.
1270 *
1271 * \retval negtaive if obj_left < obj_right
1272 * \retval 0 if obj_left == obj_right
1273 * \retval positive if obj_left > obj_right
1274 */
1275typedef int (ao2_sort_fn)(const void *obj_left, const void *obj_right, int flags);
1276
1277/*! \name Object Containers
1278 * Here start declarations of containers.
1279 *
1280 * @{
1281 */
1282struct ao2_container;
1283
1284/*!
1285 * \brief Allocate and initialize a hash container with the desired number of buckets.
1286 *
1287 * \details
1288 * We allocate space for a struct astobj_container, struct container
1289 * and the buckets[] array.
1290 *
1291 * \param ao2_options Container ao2 object options (See enum ao2_alloc_opts)
1292 * \param container_options Container behaviour options (See enum ao2_container_opts)
1293 * \param n_buckets Number of buckets for hash
1294 * \param hash_fn Pointer to a function computing a hash value. (NULL if everyting goes in first bucket.)
1295 * \param sort_fn Pointer to a sort function. (NULL to not sort the buckets.)
1296 * \param cmp_fn Pointer to a compare function used by ao2_find. (NULL to match everything)
1297 *
1298 * \return A pointer to a struct container.
1299 *
1300 * \note Destructor is set implicitly.
1301 */
1302#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn) \
1303 __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1304
1305#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag) \
1306 __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1307
1308struct ao2_container *__ao2_container_alloc_hash(unsigned int ao2_options,
1309 unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn,
1311 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
1312
1313/*!
1314 * \brief Allocate and initialize a list container.
1315 *
1316 * \param ao2_options Container ao2 object options (See enum ao2_alloc_opts)
1317 * \param container_options Container behaviour options (See enum ao2_container_opts)
1318 * \param sort_fn Pointer to a sort function. (NULL if list not sorted.)
1319 * \param cmp_fn Pointer to a compare function used by ao2_find. (NULL to match everything)
1320 *
1321 * \return A pointer to a struct container.
1322 *
1323 * \note Destructor is set implicitly.
1324 * \note Implemented as a degenerate hash table.
1325 */
1326#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn) \
1327 __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1328
1329#define ao2_t_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn, tag) \
1330 __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1331
1332struct ao2_container *__ao2_container_alloc_list(unsigned int ao2_options,
1333 unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
1334 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
1335
1336/*!
1337 * \brief Allocate and initialize a red-black tree container.
1338 *
1339 * \param ao2_options Container ao2 object options (See enum ao2_alloc_opts)
1340 * \param container_options Container behaviour options (See enum ao2_container_opts)
1341 * \param sort_fn Pointer to a sort function.
1342 * \param cmp_fn Pointer to a compare function used by ao2_find. (NULL to match everything)
1343 *
1344 * \return A pointer to a struct container.
1345 *
1346 * \note Destructor is set implicitly.
1347 */
1348#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn) \
1349 __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1350
1351#define ao2_t_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn, tag) \
1352 __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1353
1354struct ao2_container *__ao2_container_alloc_rbtree(unsigned int ao2_options, unsigned int container_options,
1356 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
1357
1358/*! \brief
1359 * Returns the number of elements in a container.
1360 */
1362
1363/*!
1364 * \brief Copy all object references in the src container into the dest container.
1365 * \since 11.0
1366 *
1367 * \param dest Container to copy src object references into.
1368 * \param src Container to copy all object references from.
1369 * \param flags OBJ_NOLOCK if a lock is already held on both containers.
1370 * Otherwise, the src container is locked first.
1371 *
1372 * \pre The dest container must be empty. If the duplication fails, the
1373 * dest container will be returned empty.
1374 *
1375 * \note This can potentially be expensive because a malloc is
1376 * needed for every object in the src container.
1377 *
1378 * \retval 0 on success.
1379 * \retval -1 on error.
1380 */
1381int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags);
1382
1383/*!
1384 * \brief Copy object references associated with src container weakproxies into the dest container.
1385 *
1386 * \param dest Container to copy src strong object references into.
1387 * \param src Container to copy all weak object references from.
1388 * \param flags OBJ_NOLOCK if a lock is already held on both containers.
1389 * Otherwise, the src container is locked first.
1390 *
1391 * \pre The dest container must be empty. If the duplication fails, the
1392 * dest container will be returned empty.
1393 *
1394 * \note This can potentially be expensive because a malloc is
1395 * needed for every object in the src container.
1396 *
1397 * \note Every object inside the container is locked by \ref ao2_weakproxy_get_object.
1398 * Any weakproxy in \p src with no associated object is ignored.
1399 *
1400 * \retval 0 on success.
1401 * \retval -1 on error.
1402 */
1403int ao2_container_dup_weakproxy_objs(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags);
1404
1405/*!
1406 * \brief Create a clone/copy of the given container.
1407 * \since 11.0
1408 *
1409 * \param orig Container to copy all object references from.
1410 * \param flags OBJ_NOLOCK if a lock is already held on the container.
1411 *
1412 * \note This can potentially be expensive because a malloc is
1413 * needed for every object in the orig container.
1414 *
1415 * \return Clone container on success.
1416 * \retval NULL on error.
1417 */
1418#define ao2_container_clone(orig, flags) \
1419 __ao2_container_clone(orig, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1420
1421#define ao2_t_container_clone(orig, flags, tag) \
1422 __ao2_container_clone(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1423
1424struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags,
1425 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
1426
1427/*!
1428 * \brief Print output.
1429 * \since 12.0.0
1430 *
1431 * \param where User data pointer needed to determine where to put output.
1432 * \param fmt printf type format string.
1433 */
1434typedef void (ao2_prnt_fn)(void *where, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
1435
1436/*!
1437 * \brief Print object key.
1438 * \since 12.0.0
1439 *
1440 * \param v_obj A pointer to the object we want the key printed.
1441 * \param where User data needed by prnt to determine where to put output.
1442 * \param prnt Print output callback function to use.
1443 */
1444typedef void (ao2_prnt_obj_fn)(void *v_obj, void *where, ao2_prnt_fn *prnt);
1445
1446/*!
1447 * \brief Display contents of the specified container.
1448 * \since 12.0.0
1449 *
1450 * \param self Container to dump.
1451 * \param flags OBJ_NOLOCK if a lock is already held on the container.
1452 * \param name Container name. (NULL if anonymous)
1453 * \param where User data needed by prnt to determine where to put output.
1454 * \param prnt Print output callback function to use.
1455 * \param prnt_obj Callback function to print the given object's key. (NULL if not available)
1456 */
1457void ao2_container_dump(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj);
1458
1459/*!
1460 * \brief Display statistics of the specified container.
1461 * \since 12.0.0
1462 *
1463 * \param self Container to display statistics.
1464 * \param flags OBJ_NOLOCK if a lock is already held on the container.
1465 * \param name Container name. (NULL if anonymous)
1466 * \param where User data needed by prnt to determine where to put output.
1467 * \param prnt Print output callback function to use.
1468 */
1469void ao2_container_stats(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt);
1470
1471/*!
1472 * \brief Perform an integrity check on the specified container.
1473 * \since 12.0.0
1474 *
1475 * \param self Container to check integrity.
1476 * \param flags OBJ_NOLOCK if a lock is already held on the container.
1477 *
1478 * \retval 0 on success.
1479 * \retval -1 on error.
1480 */
1481int ao2_container_check(struct ao2_container *self, enum search_flags flags);
1482
1483/*!
1484 * \brief Register a container for CLI stats and integrity check.
1485 * \since 12.0.0
1486 *
1487 * \param name Name to register the container under.
1488 * \param self Container to register.
1489 * \param prnt_obj Callback function to print the given object's key. (NULL if not available)
1490 *
1491 * \retval 0 on success.
1492 * \retval -1 on error.
1493 */
1494int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj);
1495
1496/*!
1497 * \brief Unregister a container for CLI stats and integrity check.
1498 * \since 12.0.0
1499 *
1500 * \param name Name the container is registered under.
1501 */
1502void ao2_container_unregister(const char *name);
1503
1504/*! @} */
1505
1506/*! \name Object Management
1507 * Here we have functions to manage objects.
1508 *
1509 * We can use the functions below on any kind of
1510 * object defined by the user.
1511 *
1512 * @{
1513 */
1514
1515/*!
1516 * \brief Add an object to a container.
1517 *
1518 * \param container The container to operate on.
1519 * \param obj The object to be added.
1520 *
1521 * \retval 0 on errors.
1522 * \retval 1 on success.
1523 *
1524 * This function inserts an object in a container according its key.
1525 *
1526 * \note Remember to set the key before calling this function.
1527 *
1528 * \note This function automatically increases the reference count to account
1529 * for the reference that the container now holds to the object.
1530 */
1531#define ao2_link(container, obj) \
1532 __ao2_link((container), (obj), 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1533#define ao2_t_link(container, obj, tag) \
1534 __ao2_link((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1535
1536/*!
1537 * \brief Add an object to a container.
1538 *
1539 * \param container The container to operate on.
1540 * \param obj The object to be added.
1541 * \param flags search_flags to control linking the object. (OBJ_NOLOCK)
1542 *
1543 * \retval 0 on errors.
1544 * \retval 1 on success.
1545 *
1546 * This function inserts an object in a container according its key.
1547 *
1548 * \note Remember to set the key before calling this function.
1549 *
1550 * \note This function automatically increases the reference count to account
1551 * for the reference that the container now holds to the object.
1552 */
1553#define ao2_link_flags(container, obj, flags) \
1554 __ao2_link((container), (obj), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1555#define ao2_t_link_flags(container, obj, flags, tag) \
1556 __ao2_link((container), (obj), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1557
1558int __ao2_link(struct ao2_container *c, void *obj_new, int flags,
1559 const char *tag, const char *file, int line, const char *func);
1560
1561/*!
1562 * \brief Remove an object from a container
1563 *
1564 * \param container The container to operate on.
1565 * \param obj The object to unlink.
1566 *
1567 * \retval NULL always
1568 *
1569 * \note The object requested to be unlinked must be valid. However, if it turns
1570 * out that it is not in the container, this function is still safe to
1571 * be called.
1572 *
1573 * \note If the object gets unlinked from the container, the container's
1574 * reference to the object will be automatically released. (The
1575 * refcount will be decremented).
1576 */
1577#define ao2_unlink(container, obj) \
1578 __ao2_unlink((container), (obj), 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1579#define ao2_t_unlink(container, obj, tag) \
1580 __ao2_unlink((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1581
1582/*!
1583 * \brief Remove an object from a container
1584 *
1585 * \param container The container to operate on.
1586 * \param obj The object to unlink.
1587 * \param flags search_flags to control unlinking the object. (OBJ_NOLOCK)
1588 *
1589 * \retval NULL always
1590 *
1591 * \note The object requested to be unlinked must be valid. However, if it turns
1592 * out that it is not in the container, this function is still safe to
1593 * be called.
1594 *
1595 * \note If the object gets unlinked from the container, the container's
1596 * reference to the object will be automatically released. (The
1597 * refcount will be decremented).
1598 */
1599#define ao2_unlink_flags(container, obj, flags) \
1600 __ao2_unlink((container), (obj), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1601
1602#define ao2_t_unlink_flags(container, obj, flags, tag) \
1603 __ao2_unlink((container), (obj), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1604
1605void *__ao2_unlink(struct ao2_container *c, void *obj, int flags,
1606 const char *tag, const char *file, int line, const char *func);
1607
1608/*! @} */
1609
1610
1611/*! \brief
1612 * ao2_callback() is a generic function that applies cb_fn() to all objects
1613 * in a container, as described below.
1614 *
1615 * \param c A pointer to the container to operate on.
1616 * \param flags A set of flags specifying the operation to perform,
1617 * partially used by the container code, but also passed to
1618 * the callback.
1619 * - If OBJ_NODATA is set, ao2_callback will return NULL. No refcounts
1620 * of any of the traversed objects will be incremented.
1621 * On the converse, if it is NOT set (the default), the ref count
1622 * of the first matching object will be incremented and returned.
1623 * - If OBJ_MULTIPLE is set, the ref count of all matching objects will
1624 * be incremented in an iterator for a temporary container and returned.
1625 * - If OBJ_SEARCH_OBJECT is set, the traversed items will be restricted
1626 * to the objects in the bucket that the object key hashes to.
1627 * - If OBJ_SEARCH_KEY is set, the traversed items will be restricted
1628 * to the objects in the bucket that the object key hashes to.
1629 * \param cb_fn A function pointer, that will be called on all
1630 * objects, to see if they match. This function returns CMP_MATCH
1631 * if the object is matches the criteria; CMP_STOP if the traversal
1632 * should immediately stop, or both (via bitwise ORing), if you find a
1633 * match and want to end the traversal, and 0 if the object is not a match,
1634 * but the traversal should continue. This is the function that is applied
1635 * to each object traversed. Its arguments are:
1636 * (void *obj, void *arg, int flags), where:
1637 * obj is an object
1638 * arg is the same as arg passed into ao2_callback
1639 * flags is the same as flags passed into ao2_callback (flags are
1640 * also used by ao2_callback).
1641 * \param arg passed to the callback.
1642 *
1643 * \retval NULL on failure or no matching object found.
1644 *
1645 * \return object found if OBJ_MULTIPLE is not set in the flags
1646 * parameter.
1647 *
1648 * \return ao2_iterator pointer if OBJ_MULTIPLE is set in the
1649 * flags parameter. The iterator must be destroyed with
1650 * ao2_iterator_destroy() when the caller no longer needs it.
1651 *
1652 * If the function returns any objects, their refcount is incremented,
1653 * and the caller is in charge of decrementing them once done.
1654 *
1655 * Typically, ao2_callback() is used for two purposes:
1656 * - to perform some action (including removal from the container) on one
1657 * or more objects; in this case, cb_fn() can modify the object itself,
1658 * and to perform deletion should set CMP_MATCH on the matching objects,
1659 * and have OBJ_UNLINK set in flags.
1660 * - to look for a specific object in a container; in this case, cb_fn()
1661 * should not modify the object, but just return a combination of
1662 * CMP_MATCH and CMP_STOP on the desired object.
1663 * Other usages are also possible, of course.
1664 *
1665 * This function searches through a container and performs operations
1666 * on objects according on flags passed.
1667 * XXX describe better
1668 * The comparison is done calling the compare function set implicitly.
1669 * The arg pointer can be a pointer to an object or to a key,
1670 * we can say this looking at flags value.
1671 * If arg points to an object we will search for the object pointed
1672 * by this value, otherwise we search for a key value.
1673 * If the key is not unique we only find the first matching value.
1674 *
1675 * The use of flags argument is the follow:
1676 *
1677 * OBJ_UNLINK unlinks the object found
1678 * OBJ_NODATA on match, do not return an object
1679 * Callbacks use OBJ_NODATA as a default
1680 * functions such as find() do
1681 * OBJ_MULTIPLE return multiple matches
1682 * Default is no.
1683 * OBJ_SEARCH_OBJECT the pointer is to an object
1684 * OBJ_SEARCH_KEY the pointer is to a search key
1685 * OBJ_SEARCH_PARTIAL_KEY the pointer is to a partial search key
1686 *
1687 * \note When the returned object is no longer in use, ao2_ref() should
1688 * be used to free the additional reference possibly created by this function.
1689 *
1690 * @{
1691 */
1692#define ao2_callback(c, flags, cb_fn, arg) \
1693 __ao2_callback((c), (flags), (cb_fn), (arg), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1694
1695#define ao2_t_callback(c, flags, cb_fn, arg, tag) \
1696 __ao2_callback((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1697
1698void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
1699 ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
1700 const char *func);
1701
1702/*! @} */
1703
1704/*! \brief
1705 * ao2_callback_data() is a generic function that applies cb_fn() to all objects
1706 * in a container. It is functionally identical to ao2_callback() except that
1707 * instead of taking an ao2_callback_fn *, it takes an ao2_callback_data_fn *, and
1708 * allows the caller to pass in arbitrary data.
1709 *
1710 * This call would be used instead of ao2_callback() when the caller needs to pass
1711 * OBJ_SEARCH_OBJECT, OBJ_SEARCH_KEY, or OBJ_SEARCH_PARTIAL_KEY as part of the flags
1712 * argument (which in turn requires passing in a known pointer type for 'arg') and
1713 * also needs access to other non-global data to complete it's comparison or task.
1714 *
1715 * See the documentation for ao2_callback() for argument descriptions.
1716 *
1717 * \see ao2_callback()
1718 */
1719
1720#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \
1721 __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1722#define ao2_callback_data(container, flags, cb_fn, arg, data) \
1723 __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1724
1725void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
1726 ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
1727 int line, const char *func);
1728
1729/*! ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg)
1730 * XXX possibly change order of arguments ?
1731 */
1732
1733#define ao2_t_find(container, arg, flags, tag) \
1734 __ao2_find((container), (arg), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1735#define ao2_find(container, arg, flags) \
1736 __ao2_find((container), (arg), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1737
1738void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags,
1739 const char *tag, const char *file, int line, const char *func);
1740
1741/*!
1742 * \brief Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.
1743 *
1744 * \note Only OBJ_SEARCH_* and OBJ_NOLOCK flags are supported by this function.
1745 * \see ao2_callback for description of arguments.
1746 */
1747#define ao2_weakproxy_find(c, arg, flags, tag) \
1748 __ao2_weakproxy_find(c, arg, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1749void *__ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags,
1750 const char *tag, const char *file, int line, const char *func);
1751
1752/*! \brief
1753 *
1754 *
1755 * When we need to walk through a container, we use an
1756 * ao2_iterator to keep track of the current position.
1757 *
1758 * Because the navigation is typically done without holding the
1759 * lock on the container across the loop, objects can be
1760 * inserted or deleted or moved while we work. As a
1761 * consequence, there is no guarantee that we manage to touch
1762 * all the elements in the container, and it is possible that we
1763 * touch the same object multiple times.
1764 *
1765 * An iterator must be first initialized with
1766 * ao2_iterator_init(), then we can use o = ao2_iterator_next()
1767 * to move from one element to the next. Remember that the
1768 * object returned by ao2_iterator_next() has its refcount
1769 * incremented, and the reference must be explicitly released
1770 * when done with it.
1771 *
1772 * In addition, ao2_iterator_init() will hold a reference to the
1773 * container being iterated and the last container node found.
1774 * These objects will be unreffed when ao2_iterator_destroy() is
1775 * called to free up the resources used by the iterator (if
1776 * any).
1777 *
1778 * Example:
1779 *
1780 * \code
1781 *
1782 * struct ao2_container *c = ... // the container we want to iterate on
1783 * struct ao2_iterator i;
1784 * struct my_obj *o;
1785 *
1786 * i = ao2_iterator_init(c, flags);
1787 *
1788 * while ((o = ao2_iterator_next(&i))) {
1789 * ... do something on o ...
1790 * ao2_ref(o, -1);
1791 * }
1792 *
1793 * ao2_iterator_restart(&i);
1794 * while ((o = ao2_iterator_next(&i))) {
1795 * ... do something on o ...
1796 * ao2_ref(o, -1);
1797 * }
1798 *
1799 * ao2_iterator_destroy(&i);
1800 *
1801 * \endcode
1802 *
1803 */
1804
1805/*!
1806 * \brief The astobj2 iterator
1807 *
1808 * \note You are not supposed to know the internals of an iterator!
1809 * We would like the iterator to be opaque, unfortunately
1810 * its size needs to be known if we want to store it around
1811 * without too much trouble.
1812 * Anyways...
1813 * The iterator has a pointer to the container, and a flags
1814 * field specifying various things e.g. whether the container
1815 * should be locked or not while navigating on it.
1816 * The iterator "points" to the current container node.
1817 *
1818 * Details are in the implementation of ao2_iterator_next()
1819 */
1820struct ao2_iterator {
1821 /*! The container (Has a reference) */
1822 struct ao2_container *c;
1823 /*! Last container node (Has a reference) */
1824 void *last_node;
1825 /*! Nonzero if the iteration has completed. */
1826 int complete;
1827 /*! operation flags (enum ao2_iterator_flags) */
1828 int flags;
1829};
1830
1831/*! Flags that can be passed to ao2_iterator_init() to modify the behavior
1832 * of the iterator.
1833 */
1834enum ao2_iterator_flags {
1835 /*!
1836 * \brief Assume that the ao2_container is already locked.
1837 *
1838 * \note For ao2_containers that have mutexes, no locking will
1839 * be done.
1840 *
1841 * \note For ao2_containers that have RWLOCKs, the lock will be
1842 * promoted to write mode as needed. The lock will be returned
1843 * to the original locked state.
1844 *
1845 * \note Only use this flag if the ao2_container is manually
1846 * locked already. You should hold the lock until after
1847 * ao2_iterator_destroy(). If you must release the lock then
1848 * you must at least hold the lock whenever you call an
1849 * ao2_iterator_xxx function with this iterator.
1850 */
1851 AO2_ITERATOR_DONTLOCK = (1 << 0),
1852 /*!
1853 * Indicates that the iterator was dynamically allocated by
1854 * astobj2 API and should be freed by ao2_iterator_destroy().
1855 */
1856 AO2_ITERATOR_MALLOCD = (1 << 1),
1857 /*!
1858 * Indicates that before the iterator returns an object from
1859 * the container being iterated, the object should be unlinked
1860 * from the container.
1861 */
1862 AO2_ITERATOR_UNLINK = (1 << 2),
1863 /*!
1864 * Iterate in descending order (Last to first container object)
1865 * (Otherwise ascending order)
1866 *
1867 * \note Other traversal orders such as pre-order and post-order
1868 * do not make sense because they require the container
1869 * structure to be static during the traversal. Iterators just
1870 * about guarantee that is not going to happen because the
1871 * container is allowed to change by other threads during the
1872 * iteration.
1873 */
1874 AO2_ITERATOR_DESCENDING = (1 << 3),
1875};
1876
1877/*!
1878 * \brief Create an iterator for a container
1879 *
1880 * \param c the container
1881 * \param flags one or more flags from ao2_iterator_flags.
1882 *
1883 * \return the constructed iterator
1884 *
1885 * \note This function does \b not take a pointer to an iterator;
1886 * rather, it returns an iterator structure that should be
1887 * assigned to (overwriting) an existing iterator structure
1888 * allocated on the stack or on the heap.
1889 *
1890 * This function will take a reference on the container being iterated.
1891 */
1893
1894/*!
1895 * \brief Destroy a container iterator
1896 *
1897 * \param iter the iterator to destroy
1898 *
1899 * This function will release the container reference held by the iterator
1900 * and any other resources it may be holding.
1901 */
1902#if defined(TEST_FRAMEWORK)
1903void ao2_iterator_destroy(struct ao2_iterator *iter) __attribute__((noinline));
1904#else
1905void ao2_iterator_destroy(struct ao2_iterator *iter);
1906#endif /* defined(TEST_FRAMEWORK) */
1907
1908#define ao2_t_iterator_next(iter, tag) \
1909 __ao2_iterator_next((iter), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1910#define ao2_iterator_next(iter) \
1911 __ao2_iterator_next((iter), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1912
1913void *__ao2_iterator_next(struct ao2_iterator *iter,
1914 const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
1915
1916/*!
1917 * \brief Restart an iteration.
1918 *
1919 * \param iter the iterator to restart
1920 *
1921 * \note A restart is not going to have any effect if the
1922 * iterator was created with the AO2_ITERATOR_UNLINK flag. Any
1923 * previous objects returned were removed from the container.
1924 */
1925void ao2_iterator_restart(struct ao2_iterator *iter);
1926
1927/*! gcc __attribute__(cleanup()) functions
1928 * \note they must be able to handle NULL parameters because most of the
1929 * allocation/find functions can fail and we don't want to try to tear
1930 * down a NULL */
1931void __ao2_cleanup(void *obj);
1932void __ao2_cleanup_debug(void *obj, const char *tag, const char *file, int line, const char *function);
1933#define ao2_cleanup(obj) __ao2_cleanup_debug((obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
1934#define ao2_t_cleanup(obj, tag) __ao2_cleanup_debug((obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
1935void ao2_iterator_cleanup(struct ao2_iterator *iter);
1936
1937/*!
1938 * \brief Get a count of the iterated container objects.
1939 *
1940 * \param iter the iterator to query
1941 *
1942 * \return The number of objects in the iterated container
1943 */
1944int ao2_iterator_count(struct ao2_iterator *iter);
1945
1946/*!
1947 * \brief Creates a hash function for a structure field.
1948 * \param stype The structure type
1949 * \param field The string field in the structure to hash
1950 * \param hash_fn Function which hashes the field
1951 *
1952 * AO2_FIELD_HASH_FN(mystruct, myfield, ast_str_hash) will
1953 * produce a function named mystruct_hash_fn which hashes
1954 * mystruct->myfield with ast_str_hash.
1955 */
1956#define AO2_FIELD_HASH_FN(stype, field, hash_fn) \
1957static int stype ## _hash_fn(const void *obj, const int flags) \
1958{ \
1959 const struct stype *object = obj; \
1960 const char *key; \
1961 switch (flags & OBJ_SEARCH_MASK) { \
1962 case OBJ_SEARCH_KEY: \
1963 key = obj; \
1964 break; \
1965 case OBJ_SEARCH_OBJECT: \
1966 key = object->field; \
1967 break; \
1968 default: \
1969 ast_assert(0); \
1970 return 0; \
1971 } \
1972 return hash_fn(key); \
1973}
1974
1975
1976#define AO2_FIELD_TRANSFORM_CMP_FN(cmp) ((cmp) ? 0 : CMP_MATCH)
1977#define AO2_FIELD_TRANSFORM_SORT_FN(cmp) (cmp)
1978
1979/*!
1980 * \internal
1981 *
1982 * \brief Creates a compare function for a structure string field.
1983 * \param stype The structure type
1984 * \param fn_suffix Function name suffix
1985 * \param field The string field in the structure to compare
1986 * \param key_cmp Key comparison function like strcmp
1987 * \param partial_key_cmp Partial key comparison function like strncmp
1988 * \param transform A macro that takes the cmp result as an argument
1989 * and transforms it to a return value.
1990 * \param argconst
1991 *
1992 * Do not use this macro directly, instead use macro's starting with
1993 * AST_STRING_FIELD.
1994 *
1995 * \warning The macro is an internal implementation detail, the API
1996 * may change at any time.
1997 */
1998#define AO2_FIELD_CMP_FN(stype, fn_suffix, field, key_cmp, partial_key_cmp, transform, argconst) \
1999static int stype ## fn_suffix(argconst void *obj, argconst void *arg, int flags) \
2000{ \
2001 const struct stype *object_left = obj, *object_right = arg; \
2002 const char *right_key = arg; \
2003 int cmp; \
2004 switch (flags & OBJ_SEARCH_MASK) { \
2005 case OBJ_SEARCH_OBJECT: \
2006 right_key = object_right->field; \
2007 case OBJ_SEARCH_KEY: \
2008 cmp = key_cmp(object_left->field, right_key); \
2009 break; \
2010 case OBJ_SEARCH_PARTIAL_KEY: \
2011 cmp = partial_key_cmp(object_left->field, right_key, strlen(right_key)); \
2012 break; \
2013 default: \
2014 cmp = 0; \
2015 break; \
2016 } \
2017 return transform(cmp); \
2018}
2019
2020/*!
2021 * \brief Creates a hash function for a structure string field.
2022 * \param stype The structure type
2023 * \param field The string field in the structure to hash
2024 *
2025 * AO2_STRING_FIELD_HASH_FN(mystruct, myfield) will produce a function
2026 * named mystruct_hash_fn which hashes mystruct->myfield.
2027 *
2028 * AO2_STRING_FIELD_HASH_FN(mystruct, myfield) would do the same except
2029 * it uses the hash function which ignores case.
2030 */
2031#define AO2_STRING_FIELD_HASH_FN(stype, field) \
2032 AO2_FIELD_HASH_FN(stype, field, ast_str_hash)
2033#define AO2_STRING_FIELD_CASE_HASH_FN(stype, field) \
2034 AO2_FIELD_HASH_FN(stype, field, ast_str_case_hash)
2035
2036/*!
2037 * \brief Creates a compare function for a structure string field.
2038 * \param stype The structure type
2039 * \param field The string field in the structure to compare
2040 *
2041 * AO2_STRING_FIELD_CMP_FN(mystruct, myfield) will produce a function
2042 * named mystruct_cmp_fn which compares mystruct->myfield.
2043 *
2044 * AO2_STRING_FIELD_CASE_CMP_FN(mystruct, myfield) would do the same
2045 * except it performs case insensitive comparisons.
2046 */
2047#define AO2_STRING_FIELD_CMP_FN(stype, field) \
2048 AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_CMP_FN,)
2049#define AO2_STRING_FIELD_CASE_CMP_FN(stype, field) \
2050 AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_CMP_FN,)
2051
2052/*!
2053 * \brief Creates a sort function for a structure string field.
2054 * \param stype The structure type
2055 * \param field The string field in the structure to compare
2056 *
2057 * AO2_STRING_FIELD_SORT_FN(mystruct, myfield) will produce a function
2058 * named mystruct_sort_fn which compares mystruct->myfield.
2059 *
2060 * AO2_STRING_FIELD_CASE_SORT_FN(mystruct, myfield) would do the same
2061 * except it performs case insensitive comparisons.
2062 */
2063#define AO2_STRING_FIELD_SORT_FN(stype, field) \
2064 AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_SORT_FN, const)
2065#define AO2_STRING_FIELD_CASE_SORT_FN(stype, field) \
2066 AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_SORT_FN, const)
2067
2068#endif /* _ASTERISK_ASTOBJ2_H */
ast_mutex_t lock
Definition app_sla.c:337
#define var
Definition ast_expr2f.c:605
void * __ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result
void * __ao2_iterator_next(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
void() ao2_prnt_obj_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)
Print object key.
Definition astobj2.h:1445
int ao2_weakproxy_unsubscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Remove notification of real object destruction.
Definition astobj2.c:973
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Request notification when weakproxy points to NULL.
Definition astobj2.c:934
_cb_results
A callback function will return a combination of CMP_MATCH and CMP_STOP. The latter will terminate th...
Definition astobj2.h:1026
@ CMP_MATCH
Definition astobj2.h:1027
@ CMP_STOP
Definition astobj2.h:1028
void * __ao2_global_obj_ref(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result
void ao2_iterator_cleanup(struct ao2_iterator *iter)
int __ao2_trylock(void *a, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
Try locking– (don't block if fail)
Definition astobj2.c:342
int ao2_container_dup_weakproxy_objs(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy object references associated with src container weakproxies into the dest container.
int ao2_match_by_addr(void *obj, void *arg, int flags)
A common ao2_callback is one that matches by address.
int ao2_container_check(struct ao2_container *self, enum search_flags flags)
Perform an integrity check on the specified container.
void * __ao2_callback_data(struct ao2_container *c, enum search_flags flags, ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file, int line, const char *func)
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
ao2_lock_req
Which lock to request.
Definition astobj2.h:700
@ AO2_LOCK_REQ_MUTEX
Definition astobj2.h:702
@ AO2_LOCK_REQ_WRLOCK
Definition astobj2.h:706
@ AO2_LOCK_REQ_RDLOCK
Definition astobj2.h:704
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
void * __ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line, const char *func)
void * __ao2_weakproxy_get_object(void *weakproxy, int flags, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition astobj2.c:889
void(* ao2_weakproxy_notification_cb)(void *weakproxy, void *data)
Definition astobj2.h:526
void ao2_container_stats(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt)
Display statistics of the specified container.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
Definition astobj2.h:1226
ao2_iterator_flags
Definition astobj2.h:1835
@ AO2_ITERATOR_UNLINK
Definition astobj2.h:1863
@ AO2_ITERATOR_DONTLOCK
Assume that the ao2_container is already locked.
Definition astobj2.h:1852
@ AO2_ITERATOR_MALLOCD
Definition astobj2.h:1857
@ AO2_ITERATOR_DESCENDING
Definition astobj2.h:1875
int __ao2_weakproxy_ref_object(void *weakproxy, int delta, int flags, const char *tag, const char *file, int line, const char *func)
Definition astobj2.c:862
void(* ao2_destructor_fn)(void *vdoomed)
Typedef for an object destructor.
Definition astobj2.h:358
int __ao2_link(struct ao2_container *c, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func)
int ao2_ref_and_lock(void *obj)
Increment reference count on an object and lock it.
Definition astobj2.h:780
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int ao2_iterator_count(struct ao2_iterator *iter)
Get a count of the iterated container objects.
int() ao2_sort_fn(const void *obj_left, const void *obj_right, int flags)
Type of generic container sort function.
Definition astobj2.h:1276
void ao2_iterator_restart(struct ao2_iterator *iter)
Restart an iteration.
#define ao2_unlock(a)
Definition astobj2.h:729
struct ao2_container * __ao2_container_alloc_list(unsigned int ao2_options, unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
struct ao2_container * __ao2_container_alloc_rbtree(unsigned int ao2_options, unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
void * __ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
int() ao2_hash_fn(const void *obj, int flags)
Definition astobj2.h:1258
int __ao2_weakproxy_set_object(void *weakproxy, void *obj, int flags, const char *tag, const char *file, int line, const char *func)
Definition astobj2.c:818
struct ao2_container * __ao2_container_alloc_hash(unsigned int ao2_options, unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
#define ao2_lock(a)
Definition astobj2.h:717
void * __ao2_weakproxy_find(struct ao2_container *c, const void *arg, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
struct ao2_container * __ao2_container_clone(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
int __ao2_global_obj_replace_unref(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)
void __ao2_cleanup(void *obj)
Definition astobj2.c:677
int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
Register a container for CLI stats and integrity check.
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition astobj2.c:476
void ao2_container_dump(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj)
Display contents of the specified container.
void * __ao2_weakproxy_alloc(size_t data_size, ao2_destructor_fn destructor_fn, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition astobj2.c:793
void __ao2_cleanup_debug(void *obj, const char *tag, const char *file, int line, const char *function)
Definition astobj2.c:670
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int() ao2_callback_data_fn(void *obj, void *arg, void *data, int flags)
Type of a generic callback function.
Definition astobj2.h:1244
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
Definition astobj2.c:498
search_flags
Flags passed to ao2_callback_fn(), ao2_hash_fn(), and ao2_sort_fn() to modify behaviour.
Definition astobj2.h:1034
@ OBJ_ORDER_MASK
Traverse order option field mask.
Definition astobj2.h:1119
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
Definition astobj2.h:1116
@ OBJ_ORDER_DESCENDING
Traverse in descending order (Last to first container object)
Definition astobj2.h:1123
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
Definition astobj2.h:1087
@ OBJ_ORDER_PRE
Traverse in pre-order (Node then children, for tree container)
Definition astobj2.h:1132
@ OBJ_ORDER_ASCENDING
Traverse in ascending order (First to last container object)
Definition astobj2.h:1121
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
Definition astobj2.h:1063
@ OBJ_NODATA
Definition astobj2.h:1044
@ OBJ_SEARCH_MASK
Search option field mask.
Definition astobj2.h:1072
@ OBJ_MULTIPLE
Definition astobj2.h:1049
@ OBJ_UNLINK
Definition astobj2.h:1039
@ OBJ_ORDER_POST
Traverse in post-order (Children then node, for tree container)
Definition astobj2.h:1141
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition astobj2.h:1101
@ OBJ_SEARCH_NONE
The arg parameter has no meaning to the astobj2 code.
Definition astobj2.h:1074
void * __ao2_unlink(struct ao2_container *c, void *obj, int flags, const char *tag, const char *file, int line, const char *func)
int __ao2_unlock(void *a, const char *file, const char *func, int line, const char *var)
Unlock an object.
Definition astobj2.c:288
int __ao2_lock(void *a, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
Lock an object.
Definition astobj2.c:222
void() ao2_prnt_fn(void *where, const char *fmt,...)
Print output.
Definition astobj2.h:1435
int ao2_unlock_and_unref(void *obj)
Unlock an object and decrement its reference count.
Definition astobj2.h:800
void * __ao2_get_weakproxy(void *obj, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition astobj2.c:917
ao2_container_opts
Options available when allocating an ao2 container object.
Definition astobj2.h:1161
@ AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT
Reject duplicate objects in container.
Definition astobj2.h:1201
@ AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN
Insert objects at the beginning of the container. (Otherwise it is the opposite; insert at the end....
Definition astobj2.h:1172
@ AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW
Allow objects with duplicate keys in container.
Definition astobj2.h:1181
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT
Reject objects with duplicate keys in container.
Definition astobj2.h:1188
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE
Replace objects with duplicate keys in container.
Definition astobj2.h:1211
@ AO2_CONTAINER_ALLOC_OPT_DUPS_MASK
The ao2 container objects with duplicate keys option field mask.
Definition astobj2.h:1177
#define attribute_warn_unused_result
Definition compiler.h:71
static const char name[]
Definition format_mp3.c:68
#define AST_INLINE_API(hdr, body)
Definition inline_api.h:54
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
Generic container type.
ao2_callback_fn * cmp_fn
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
struct ao2_container * c
Definition astobj2.h:1823
void * last_node
Definition astobj2.h:1825
This struct should be opaque, but it's size is needed.
Definition astobj2.h:529
struct ao2_weakproxy::@199 destroyed_cb
Structure for rwlock and tracking information.
Definition lock.h:164
static struct test_val a
static struct test_val c

◆ ao2_alloc_options

#define ao2_alloc_options (   data_size,
  destructor_fn,
  options 
)     __ao2_alloc((data_size), (destructor_fn), (options), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 404 of file astobj2.h.

◆ ao2_alloc_with_lockobj

#define ao2_alloc_with_lockobj (   data_size,
  destructor_fn,
  lockobj,
  tag 
)     __ao2_alloc_with_lockobj((data_size), (destructor_fn), (lockobj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Allocate and initialize an object with separate locking.

Since
14.1.0
Parameters
data_sizeThe sizeof() of the user-defined structure.
destructor_fnThe destructor function (can be NULL)
lockobjA separate ao2 object that will provide locking.
tagAn ao2 object debug tracing message.
Returns
A pointer to user-data.
See also
ao2_alloc for additional details.
Note
lockobj must be a valid AO2 object.

Definition at line 431 of file astobj2.h.

◆ ao2_bump

#define ao2_bump (   obj)     ao2_t_bump((obj), NULL)

Bump refcount on an AO2 object by one, returning the object.

Since
12

This is useful for inlining a ref bump, and you don't care about the ref count. Also NULL safe, for even more convenience.

Parameters
objAO2 object to bump the refcount on.
Returns
The given obj pointer.

Definition at line 480 of file astobj2.h.

◆ ao2_callback

#define ao2_callback (   c,
  flags,
  cb_fn,
  arg 
)     __ao2_callback((c), (flags), (cb_fn), (arg), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.

Parameters
cA pointer to the container to operate on.
flagsA 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 the first matching object will be incremented and returned.
  • If OBJ_MULTIPLE is set, the ref count of all matching objects will be incremented in an iterator for a temporary container and returned.
  • If OBJ_SEARCH_OBJECT is set, the traversed items will be restricted to the objects in the bucket that the object key hashes to.
  • If OBJ_SEARCH_KEY is set, the traversed items will be restricted to the objects in the bucket that the object key hashes to.
cb_fnA 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).
argpassed to the callback.
Return values
NULLon failure or no matching object found.
Returns
object found if OBJ_MULTIPLE is not set in the flags parameter.
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, and the caller is in charge of decrementing them once done.

Typically, ao2_callback() is used for two purposes:

  • to perform some action (including removal from the container) on one or more objects; in this case, cb_fn() can modify the object itself, and to perform deletion should set CMP_MATCH on the matching objects, and have OBJ_UNLINK set in flags.
  • to look for a specific object in a container; in this case, cb_fn() 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 The comparison is done calling the compare function set implicitly. The arg pointer can be a pointer to an object or to a key, we can say this looking at flags value. If arg points to an object we will search for the object pointed by this value, otherwise we search for a key value. If the key is not unique we only find the first matching value.

The use of flags argument is the follow:

 OBJ_UNLINK              unlinks the object found
 OBJ_NODATA              on match, do not return an object
                         Callbacks use OBJ_NODATA as a default
                         functions such as find() do
 OBJ_MULTIPLE            return multiple matches
                         Default is no.
 OBJ_SEARCH_OBJECT       the pointer is to an object
 OBJ_SEARCH_KEY          the pointer is to a search key
 OBJ_SEARCH_PARTIAL_KEY  the pointer is to a partial search 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.

Definition at line 1693 of file astobj2.h.

◆ ao2_callback_data

#define ao2_callback_data (   container,
  flags,
  cb_fn,
  arg,
  data 
)     __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1723 of file astobj2.h.

◆ ao2_cleanup

#define ao2_cleanup (   obj)    __ao2_cleanup_debug((obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
Examples
app_skel.c.

Definition at line 1934 of file astobj2.h.

◆ ao2_container_alloc_hash

#define ao2_container_alloc_hash (   ao2_options,
  container_options,
  n_buckets,
  hash_fn,
  sort_fn,
  cmp_fn 
)     __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Allocate and initialize a hash container with the desired number of buckets.

We allocate space for a struct astobj_container, struct container and the buckets[] array.

Parameters
ao2_optionsContainer ao2 object options (See enum ao2_alloc_opts)
container_optionsContainer behaviour options (See enum ao2_container_opts)
n_bucketsNumber of buckets for hash
hash_fnPointer to a function computing a hash value. (NULL if everyting goes in first bucket.)
sort_fnPointer to a sort function. (NULL to not sort the buckets.)
cmp_fnPointer to a compare function used by ao2_find. (NULL to match everything)
Returns
A pointer to a struct container.
Note
Destructor is set implicitly.
Examples
app_skel.c.

Definition at line 1303 of file astobj2.h.

◆ ao2_container_alloc_list

#define ao2_container_alloc_list (   ao2_options,
  container_options,
  sort_fn,
  cmp_fn 
)     __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Allocate and initialize a list container.

Parameters
ao2_optionsContainer ao2 object options (See enum ao2_alloc_opts)
container_optionsContainer behaviour options (See enum ao2_container_opts)
sort_fnPointer to a sort function. (NULL if list not sorted.)
cmp_fnPointer to a compare function used by ao2_find. (NULL to match everything)
Returns
A pointer to a struct container.
Note
Destructor is set implicitly.
Implemented as a degenerate hash table.
Examples
app_skel.c.

Definition at line 1327 of file astobj2.h.

◆ ao2_container_alloc_rbtree

#define ao2_container_alloc_rbtree (   ao2_options,
  container_options,
  sort_fn,
  cmp_fn 
)     __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Allocate and initialize a red-black tree container.

Parameters
ao2_optionsContainer ao2 object options (See enum ao2_alloc_opts)
container_optionsContainer behaviour options (See enum ao2_container_opts)
sort_fnPointer to a sort function.
cmp_fnPointer to a compare function used by ao2_find. (NULL to match everything)
Returns
A pointer to a struct container.
Note
Destructor is set implicitly.

Definition at line 1349 of file astobj2.h.

◆ ao2_container_clone

#define ao2_container_clone (   orig,
  flags 
)     __ao2_container_clone(orig, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Create a clone/copy of the given container.

Since
11.0
Parameters
origContainer to copy all object references from.
flagsOBJ_NOLOCK if a lock is already held on the container.
Note
This can potentially be expensive because a malloc is needed for every object in the orig container.
Returns
Clone container on success.
Return values
NULLon error.

Definition at line 1419 of file astobj2.h.

◆ AO2_FIELD_CMP_FN

#define AO2_FIELD_CMP_FN (   stype,
  fn_suffix,
  field,
  key_cmp,
  partial_key_cmp,
  transform,
  argconst 
)

Definition at line 1999 of file astobj2.h.

2001{ \
2002 const struct stype *object_left = obj, *object_right = arg; \
2003 const char *right_key = arg; \
2004 int cmp; \
2005 switch (flags & OBJ_SEARCH_MASK) { \
2006 case OBJ_SEARCH_OBJECT: \
2007 right_key = object_right->field; \
2008 case OBJ_SEARCH_KEY: \
2009 cmp = key_cmp(object_left->field, right_key); \
2010 break; \
2012 cmp = partial_key_cmp(object_left->field, right_key, strlen(right_key)); \
2013 break; \
2014 default: \
2015 cmp = 0; \
2016 break; \
2017 } \
2018 return transform(cmp); \
2019}

◆ AO2_FIELD_HASH_FN

#define AO2_FIELD_HASH_FN (   stype,
  field,
  hash_fn 
)

Creates a hash function for a structure field.

Parameters
stypeThe structure type
fieldThe string field in the structure to hash
hash_fnFunction which hashes the field

AO2_FIELD_HASH_FN(mystruct, myfield, ast_str_hash) will produce a function named mystruct_hash_fn which hashes mystruct->myfield with ast_str_hash.

Definition at line 1957 of file astobj2.h.

1959{ \
1960 const struct stype *object = obj; \
1961 const char *key; \
1962 switch (flags & OBJ_SEARCH_MASK) { \
1963 case OBJ_SEARCH_KEY: \
1964 key = obj; \
1965 break; \
1966 case OBJ_SEARCH_OBJECT: \
1967 key = object->field; \
1968 break; \
1969 default: \
1970 ast_assert(0); \
1971 return 0; \
1972 } \
1973 return hash_fn(key); \
1974}

◆ AO2_FIELD_TRANSFORM_CMP_FN

#define AO2_FIELD_TRANSFORM_CMP_FN (   cmp)    ((cmp) ? 0 : CMP_MATCH)

Definition at line 1977 of file astobj2.h.

◆ AO2_FIELD_TRANSFORM_SORT_FN

#define AO2_FIELD_TRANSFORM_SORT_FN (   cmp)    (cmp)

Definition at line 1978 of file astobj2.h.

◆ ao2_find

#define ao2_find (   container,
  arg,
  flags 
)     __ao2_find((container), (arg), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
Examples
app_skel.c.

Definition at line 1736 of file astobj2.h.

◆ ao2_get_weakproxy

#define ao2_get_weakproxy (   obj)     __ao2_get_weakproxy(obj, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Get the weakproxy attached to obj.

Since
14.0.0
Parameters
objThe object to retrieve a weakproxy from
Returns
The weakproxy object

Definition at line 688 of file astobj2.h.

◆ ao2_global_obj_ref

#define ao2_global_obj_ref (   holder)     __ao2_global_obj_ref(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Get a reference to the object stored in the global holder.

Since
11.0
Parameters
holderGlobal ao2 object holder.
Returns
Reference to current ao2 object stored in the holder.
Return values
NULLif no object available.
Examples
app_skel.c.

Definition at line 918 of file astobj2.h.

◆ ao2_global_obj_release

#define ao2_global_obj_release (   holder)     __ao2_global_obj_replace_unref(&holder, NULL, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Release the ao2 object held in the global holder.

Since
11.0
Parameters
holderGlobal ao2 object holder.
Examples
app_skel.c.

Definition at line 859 of file astobj2.h.

◆ ao2_global_obj_replace

#define ao2_global_obj_replace (   holder,
  obj 
)     __ao2_global_obj_replace(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Replace an ao2 object in the global holder.

Since
11.0
Parameters
holderGlobal ao2 object holder.
objObject to put into the holder. Can be NULL.
Note
This function automatically increases the reference count to account for the reference that the global holder now holds to the object.
Returns
Reference to previous global ao2 object stored.
Return values
NULLif no object available.

Definition at line 878 of file astobj2.h.

◆ ao2_global_obj_replace_unref

#define ao2_global_obj_replace_unref (   holder,
  obj 
)     __ao2_global_obj_replace_unref(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Replace an ao2 object in the global holder, throwing away any old object.

Since
11.0
Parameters
holderGlobal ao2 object holder.
objObject to put into the holder. Can be NULL.
Note
This function automatically increases the reference count to account for the reference that the global holder now holds to the object. It also decreases the reference count of any object being replaced.
Return values
0The global object was previously empty
1The global object was not previously empty

Definition at line 901 of file astobj2.h.

◆ AO2_GLOBAL_OBJ_STATIC

#define AO2_GLOBAL_OBJ_STATIC (   name)
Value:
struct ao2_global_obj name = { \
}
#define AST_RWLOCK_INIT_VALUE
Definition lock.h:105
ast_rwlock_t lock
Definition astobj2.h:805

Define a global object holder to be used to hold an ao2 object, statically initialized.

Since
11.0
Parameters
nameThis will be the name of the object holder.

This macro creates a global object holder that can be used to hold an ao2 object accessible using the API. The structure is allocated and initialized to be empty.

Example usage:

static AO2_GLOBAL_OBJ_STATIC(global_cfg);
#define AO2_GLOBAL_OBJ_STATIC(name)
Define a global object holder to be used to hold an ao2 object, statically initialized.
Definition astobj2.h:847

This defines global_cfg, intended to hold an ao2 object accessible using an API.

Examples
app_skel.c.

Definition at line 847 of file astobj2.h.

848 { \
849 .lock = AST_RWLOCK_INIT_VALUE, \
850 }

◆ ao2_iterator_next

#define ao2_iterator_next (   iter)     __ao2_iterator_next((iter), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
Examples
app_skel.c.

Definition at line 1911 of file astobj2.h.

◆ ao2_link

#define ao2_link (   container,
  obj 
)     __ao2_link((container), (obj), 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Add an object to a container.

Parameters
containerThe container to operate on.
objThe object to be added.
Return values
0on errors.
1on success.

This function inserts an object in a container according its key.

Note
Remember to set the key before calling this function.
This function automatically increases the reference count to account for the reference that the container now holds to the object.
Examples
app_skel.c.

Definition at line 1532 of file astobj2.h.

◆ ao2_link_flags

#define ao2_link_flags (   container,
  obj,
  flags 
)     __ao2_link((container), (obj), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Add an object to a container.

Parameters
containerThe container to operate on.
objThe object to be added.
flagssearch_flags to control linking the object. (OBJ_NOLOCK)
Return values
0on errors.
1on success.

This function inserts an object in a container according its key.

Note
Remember to set the key before calling this function.
This function automatically increases the reference count to account for the reference that the container now holds to the object.

Definition at line 1554 of file astobj2.h.

◆ ao2_lock

#define ao2_lock (   a)    __ao2_lock(a, AO2_LOCK_REQ_MUTEX, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
Examples
app_skel.c.

Definition at line 717 of file astobj2.h.

◆ ao2_rdlock

#define ao2_rdlock (   a)    __ao2_lock(a, AO2_LOCK_REQ_RDLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)

Definition at line 718 of file astobj2.h.

◆ ao2_ref

#define ao2_ref (   o,
  delta 
)    __ao2_ref((o), (delta), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Reference/unreference an object and return the old refcount.

Parameters
oA pointer to the object
deltaValue to add to the reference counter.
Returns
The value of the reference counter before the operation.

Increase/decrease the reference counter according the value of delta.

If the refcount goes to zero, the object is destroyed.

Note
The object must not be locked by the caller of this function, as it is invalid to try to unlock it after releasing the reference.
if we know the pointer to an object, it is because we have a reference count to it, so the only case when the object can go away is when we release our reference, and it is the last one in existence.
Examples
app_skel.c.

Definition at line 459 of file astobj2.h.

◆ ao2_replace

#define ao2_replace (   dst,
  src 
)     ao2_t_replace((dst), (src), NULL)

Replace one object reference with another cleaning up the original.

Since
12.4.0
Parameters
dstPointer to the object that will be cleaned up.
srcPointer to the object replacing it.

Definition at line 501 of file astobj2.h.

◆ AO2_STRING_FIELD_CASE_CMP_FN

#define AO2_STRING_FIELD_CASE_CMP_FN (   stype,
  field 
)     AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_CMP_FN,)

Definition at line 2050 of file astobj2.h.

◆ AO2_STRING_FIELD_CASE_HASH_FN

#define AO2_STRING_FIELD_CASE_HASH_FN (   stype,
  field 
)     AO2_FIELD_HASH_FN(stype, field, ast_str_case_hash)

Definition at line 2034 of file astobj2.h.

◆ AO2_STRING_FIELD_CASE_SORT_FN

#define AO2_STRING_FIELD_CASE_SORT_FN (   stype,
  field 
)     AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcasecmp, strncasecmp, AO2_FIELD_TRANSFORM_SORT_FN, const)

Definition at line 2066 of file astobj2.h.

◆ AO2_STRING_FIELD_CMP_FN

#define AO2_STRING_FIELD_CMP_FN (   stype,
  field 
)     AO2_FIELD_CMP_FN(stype, _cmp_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_CMP_FN,)

Creates a compare function for a structure string field.

Parameters
stypeThe structure type
fieldThe string field in the structure to compare

AO2_STRING_FIELD_CMP_FN(mystruct, myfield) will produce a function named mystruct_cmp_fn which compares mystruct->myfield.

AO2_STRING_FIELD_CASE_CMP_FN(mystruct, myfield) would do the same except it performs case insensitive comparisons.

Definition at line 2048 of file astobj2.h.

◆ AO2_STRING_FIELD_HASH_FN

#define AO2_STRING_FIELD_HASH_FN (   stype,
  field 
)     AO2_FIELD_HASH_FN(stype, field, ast_str_hash)

Creates a hash function for a structure string field.

Parameters
stypeThe structure type
fieldThe string field in the structure to hash

AO2_STRING_FIELD_HASH_FN(mystruct, myfield) will produce a function named mystruct_hash_fn which hashes mystruct->myfield.

AO2_STRING_FIELD_HASH_FN(mystruct, myfield) would do the same except it uses the hash function which ignores case.

Definition at line 2032 of file astobj2.h.

◆ AO2_STRING_FIELD_SORT_FN

#define AO2_STRING_FIELD_SORT_FN (   stype,
  field 
)     AO2_FIELD_CMP_FN(stype, _sort_fn, field, strcmp, strncmp, AO2_FIELD_TRANSFORM_SORT_FN, const)

Creates a sort function for a structure string field.

Parameters
stypeThe structure type
fieldThe string field in the structure to compare

AO2_STRING_FIELD_SORT_FN(mystruct, myfield) will produce a function named mystruct_sort_fn which compares mystruct->myfield.

AO2_STRING_FIELD_CASE_SORT_FN(mystruct, myfield) would do the same except it performs case insensitive comparisons.

Definition at line 2064 of file astobj2.h.

◆ ao2_t_alloc

#define ao2_t_alloc (   data_size,
  destructor_fn,
  debug_msg 
)     __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 407 of file astobj2.h.

◆ ao2_t_alloc_options

#define ao2_t_alloc_options (   data_size,
  destructor_fn,
  options,
  debug_msg 
)     __ao2_alloc((data_size), (destructor_fn), (options), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Allocate and initialize an object.

Parameters
data_sizeThe sizeof() of the user-defined structure.
destructor_fnThe destructor function (can be NULL)
optionsThe ao2 object options (See enum ao2_alloc_opts)
debug_msgAn ao2 object debug tracing message.
Returns
A pointer to user-data.

Allocates a struct astobj2 with sufficient space for the user-defined structure.

Note
  • storage is zeroed; XXX maybe we want a flag to enable/disable this.
  • the refcount of the object just created is 1
  • the returned pointer cannot be free()'d or realloc()'ed; rather, we just call ao2_ref(o, -1);

Definition at line 402 of file astobj2.h.

◆ ao2_t_bump

#define ao2_t_bump (   obj,
  tag 
)

Definition at line 483 of file astobj2.h.

484 { \
485 typeof(obj) __obj_ ## __LINE__ = (obj); \
486 if (__obj_ ## __LINE__) { \
487 ao2_t_ref(__obj_ ## __LINE__, +1, (tag)); \
488 } \
489 __obj_ ## __LINE__; \
490 })

◆ ao2_t_callback

#define ao2_t_callback (   c,
  flags,
  cb_fn,
  arg,
  tag 
)     __ao2_callback((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1696 of file astobj2.h.

◆ ao2_t_callback_data

#define ao2_t_callback_data (   container,
  flags,
  cb_fn,
  arg,
  data,
  tag 
)     __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

ao2_callback_data() is a generic function that applies cb_fn() to all objects in a container. It is functionally identical to ao2_callback() except that instead of taking an ao2_callback_fn *, it takes an ao2_callback_data_fn *, and allows the caller to pass in arbitrary data.

This call would be used instead of ao2_callback() when the caller needs to pass OBJ_SEARCH_OBJECT, OBJ_SEARCH_KEY, or OBJ_SEARCH_PARTIAL_KEY as part of the flags argument (which in turn requires passing in a known pointer type for 'arg') and also needs access to other non-global data to complete it's comparison or task.

See the documentation for ao2_callback() for argument descriptions.

See also
ao2_callback()

Definition at line 1721 of file astobj2.h.

◆ ao2_t_cleanup

#define ao2_t_cleanup (   obj,
  tag 
)    __ao2_cleanup_debug((obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1935 of file astobj2.h.

◆ ao2_t_container_alloc_hash

#define ao2_t_container_alloc_hash (   ao2_options,
  container_options,
  n_buckets,
  hash_fn,
  sort_fn,
  cmp_fn,
  tag 
)     __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1306 of file astobj2.h.

◆ ao2_t_container_alloc_list

#define ao2_t_container_alloc_list (   ao2_options,
  container_options,
  sort_fn,
  cmp_fn,
  tag 
)     __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1330 of file astobj2.h.

◆ ao2_t_container_alloc_rbtree

#define ao2_t_container_alloc_rbtree (   ao2_options,
  container_options,
  sort_fn,
  cmp_fn,
  tag 
)     __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1352 of file astobj2.h.

◆ ao2_t_container_clone

#define ao2_t_container_clone (   orig,
  flags,
  tag 
)     __ao2_container_clone(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1422 of file astobj2.h.

◆ ao2_t_find

#define ao2_t_find (   container,
  arg,
  flags,
  tag 
)     __ao2_find((container), (arg), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg) XXX possibly change order of arguments ?

Definition at line 1734 of file astobj2.h.

◆ ao2_t_get_weakproxy

#define ao2_t_get_weakproxy (   obj,
  tag 
)     __ao2_get_weakproxy(obj, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 691 of file astobj2.h.

◆ ao2_t_global_obj_ref

#define ao2_t_global_obj_ref (   holder,
  tag 
)     __ao2_global_obj_ref(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Definition at line 921 of file astobj2.h.

◆ ao2_t_global_obj_release

#define ao2_t_global_obj_release (   holder,
  tag 
)     __ao2_global_obj_replace_unref(&holder, NULL, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Definition at line 861 of file astobj2.h.

◆ ao2_t_global_obj_replace

#define ao2_t_global_obj_replace (   holder,
  obj,
  tag 
)     __ao2_global_obj_replace(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Definition at line 881 of file astobj2.h.

◆ ao2_t_global_obj_replace_unref

#define ao2_t_global_obj_replace_unref (   holder,
  obj,
  tag 
)     __ao2_global_obj_replace_unref(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)

Definition at line 904 of file astobj2.h.

◆ ao2_t_iterator_next

#define ao2_t_iterator_next (   iter,
  tag 
)     __ao2_iterator_next((iter), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1909 of file astobj2.h.

◆ ao2_t_link

#define ao2_t_link (   container,
  obj,
  tag 
)     __ao2_link((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1534 of file astobj2.h.

◆ ao2_t_link_flags

#define ao2_t_link_flags (   container,
  obj,
  flags,
  tag 
)     __ao2_link((container), (obj), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1556 of file astobj2.h.

◆ ao2_t_ref

#define ao2_t_ref (   o,
  delta,
  tag 
)    __ao2_ref((o), (delta), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 460 of file astobj2.h.

◆ ao2_t_replace

#define ao2_t_replace (   dst,
  src,
  tag 
)

Definition at line 504 of file astobj2.h.

505 {\
506 typeof(dst) *__dst_ ## __LINE__ = &dst; \
507 typeof(src) __src_ ## __LINE__ = src; \
508 if (__src_ ## __LINE__ != *__dst_ ## __LINE__) { \
509 if (__src_ ## __LINE__) {\
510 ao2_t_ref(__src_ ## __LINE__, +1, (tag)); \
511 } \
512 if (*__dst_ ## __LINE__) {\
513 ao2_t_ref(*__dst_ ## __LINE__, -1, (tag)); \
514 } \
515 *__dst_ ## __LINE__ = __src_ ## __LINE__; \
516 } \
517 }

◆ ao2_t_unlink

#define ao2_t_unlink (   container,
  obj,
  tag 
)     __ao2_unlink((container), (obj), 0, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1580 of file astobj2.h.

◆ ao2_t_unlink_flags

#define ao2_t_unlink_flags (   container,
  obj,
  flags,
  tag 
)     __ao2_unlink((container), (obj), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 1603 of file astobj2.h.

◆ ao2_t_weakproxy_alloc

#define ao2_t_weakproxy_alloc (   data_size,
  destructor_fn,
  tag 
)     __ao2_weakproxy_alloc(data_size, destructor_fn, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 553 of file astobj2.h.

◆ ao2_t_weakproxy_get_object

#define ao2_t_weakproxy_get_object (   weakproxy,
  flags,
  tag 
)     __ao2_weakproxy_get_object(weakproxy, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 624 of file astobj2.h.

◆ ao2_t_weakproxy_ref_object

#define ao2_t_weakproxy_ref_object (   weakproxy,
  delta,
  flags,
  tag 
)
Value:
__ao2_weakproxy_ref_object(weakproxy, delta, flags, \
tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 604 of file astobj2.h.

◆ ao2_t_weakproxy_set_object

#define ao2_t_weakproxy_set_object (   weakproxy,
  obj,
  flags,
  tag 
)     __ao2_weakproxy_set_object(weakproxy, obj, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Definition at line 582 of file astobj2.h.

◆ ao2_trylock

#define ao2_trylock (   a)    __ao2_trylock(a, AO2_LOCK_REQ_MUTEX, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)

Definition at line 739 of file astobj2.h.

◆ ao2_tryrdlock

#define ao2_tryrdlock (   a)    __ao2_trylock(a, AO2_LOCK_REQ_RDLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)

Definition at line 740 of file astobj2.h.

◆ ao2_trywrlock

#define ao2_trywrlock (   a)    __ao2_trylock(a, AO2_LOCK_REQ_WRLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)

Definition at line 741 of file astobj2.h.

◆ ao2_unlink

#define ao2_unlink (   container,
  obj 
)     __ao2_unlink((container), (obj), 0, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Remove an object from a container.

Parameters
containerThe container to operate on.
objThe object to unlink.
Return values
NULLalways
Note
The object requested to be unlinked must be valid. However, if it turns out that it is not in the container, this function is still safe to be called.
If the object gets unlinked from the container, the container's reference to the object will be automatically released. (The refcount will be decremented).
Examples
app_skel.c.

Definition at line 1578 of file astobj2.h.

◆ ao2_unlink_flags

#define ao2_unlink_flags (   container,
  obj,
  flags 
)     __ao2_unlink((container), (obj), (flags), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Remove an object from a container.

Parameters
containerThe container to operate on.
objThe object to unlink.
flagssearch_flags to control unlinking the object. (OBJ_NOLOCK)
Return values
NULLalways
Note
The object requested to be unlinked must be valid. However, if it turns out that it is not in the container, this function is still safe to be called.
If the object gets unlinked from the container, the container's reference to the object will be automatically released. (The refcount will be decremented).

Definition at line 1600 of file astobj2.h.

◆ ao2_unlock

#define ao2_unlock (   a)    __ao2_unlock(a, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)
Examples
app_skel.c.

Definition at line 729 of file astobj2.h.

◆ AO2_WEAKPROXY

#define AO2_WEAKPROXY ( )    struct ao2_weakproxy __weakproxy##__LINE__

Macro which must be used at the beginning of weakproxy capable objects.

Note
The primary purpose of user defined fields on weakproxy objects is to hold immutable container keys for the real object.

Definition at line 538 of file astobj2.h.

◆ ao2_weakproxy_alloc

#define ao2_weakproxy_alloc (   data_size,
  destructor_fn 
)     __ao2_weakproxy_alloc(data_size, destructor_fn, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Allocate an ao2_weakproxy object.

Since
14.0.0
Parameters
data_sizeThe sizeof() of the user-defined structure.
destructor_fnThe destructor function (can be NULL)
Note
"struct ao2_weakproxy" must be the first field of any object. This can be done by using AO2_WEAKPROXY to declare your structure.

Definition at line 550 of file astobj2.h.

◆ ao2_weakproxy_find

#define ao2_weakproxy_find (   c,
  arg,
  flags,
  tag 
)     __ao2_weakproxy_find(c, arg, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.

Note
Only OBJ_SEARCH_* and OBJ_NOLOCK flags are supported by this function.
See also
ao2_callback for description of arguments.

Definition at line 1748 of file astobj2.h.

◆ ao2_weakproxy_get_object

#define ao2_weakproxy_get_object (   weakproxy,
  flags 
)     __ao2_weakproxy_get_object(weakproxy, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Get the object associated with weakproxy.

Since
14.0.0
Parameters
weakproxyThe weakproxy to read from.
flagsOBJ_NOLOCK to avoid locking weakproxy.
Returns
A reference to the object previously set by ao2_weakproxy_set_object.
Return values
NULLEither no object was set or the previously set object has been freed.

Definition at line 621 of file astobj2.h.

◆ ao2_weakproxy_ref_object

#define ao2_weakproxy_ref_object (   weakproxy,
  delta,
  flags 
)     ao2_t_weakproxy_ref_object(weakproxy, delta, flags, NULL)

Run ao2_t_ref on the object associated with weakproxy.

Since
14.0.0
Parameters
weakproxyThe weakproxy to read from.
deltaValue to add to the reference counter.
flagsOBJ_NOLOCK to avoid locking weakproxy.
Return values
-2weakproxy is not a valid ao2_weakproxy.
-1weakproxy has no associated object.
Returns
The value of the reference counter before the operation.

Definition at line 601 of file astobj2.h.

◆ ao2_weakproxy_set_object

#define ao2_weakproxy_set_object (   weakproxy,
  obj,
  flags 
)     __ao2_weakproxy_set_object(weakproxy, obj, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Associate weakproxy with obj.

Since
14.0.0
Parameters
weakproxyAn object created by ao2_weakproxy_alloc.
objAn ao2 object not created by ao2_weakproxy_alloc.
flagsOBJ_NOLOCK to avoid locking weakproxy.
Return values
0Success
-1Failure
Note
obj must be newly created, this procedure is not thread safe if any other code can reach obj before this procedure ends.
weakproxy may be previously existing, but must not currently have an object set.
The only way to unset an object is for it to be destroyed. Any call to this function while an object is already set will fail.

Definition at line 579 of file astobj2.h.

◆ ao2_wrlock

#define ao2_wrlock (   a)    __ao2_lock(a, AO2_LOCK_REQ_WRLOCK, __FILE__, __PRETTY_FUNCTION__, __LINE__, #a)

Definition at line 719 of file astobj2.h.

◆ OBJ_KEY

#define OBJ_KEY   OBJ_SEARCH_KEY

Deprecated name

Examples
app_skel.c.

Definition at line 1151 of file astobj2.h.

◆ OBJ_PARTIAL_KEY

#define OBJ_PARTIAL_KEY   OBJ_SEARCH_PARTIAL_KEY

Deprecated name

Definition at line 1152 of file astobj2.h.

◆ OBJ_POINTER

#define OBJ_POINTER   OBJ_SEARCH_OBJECT

Deprecated name

Definition at line 1150 of file astobj2.h.

Typedef Documentation

◆ ao2_callback_data_fn

typedef int() ao2_callback_data_fn(void *obj, void *arg, void *data, int flags)

Type of a generic callback function.

Parameters
objpointer to the (user-defined part) of an object.
argcallback argument from ao2_callback()
dataarbitrary data from ao2_callback()
flagsflags from ao2_callback() OBJ_SEARCH_OBJECT - if set, 'arg', is an object. OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object. OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.

The return values are a combination of enum _cb_results. Callback functions are used to search or manipulate objects in a container.

Definition at line 1244 of file astobj2.h.

◆ ao2_callback_fn

typedef int() ao2_callback_fn(void *obj, void *arg, int flags)

Type of a generic callback function.

Parameters
objpointer to the (user-defined part) of an object.
argcallback argument from ao2_callback()
flagsflags from ao2_callback() OBJ_SEARCH_OBJECT - if set, 'arg', is an object. OBJ_SEARCH_KEY - if set, 'arg', is a search key item that is not an object. OBJ_SEARCH_PARTIAL_KEY - if set, 'arg', is a partial search key item that is not an object.

The return values are a combination of enum _cb_results. Callback functions are used to search or manipulate objects in a container.

Definition at line 1226 of file astobj2.h.

◆ ao2_destructor_fn

typedef void(* ao2_destructor_fn) (void *vdoomed)

Typedef for an object destructor.

Parameters
vdoomedObject to destroy.

This is called just before freeing the memory for the object. It is passed a pointer to the user-defined data of the object.

Definition at line 358 of file astobj2.h.

◆ ao2_hash_fn

typedef int() ao2_hash_fn(const void *obj, int flags)

Type of a generic function to generate a hash value from an object.

Parameters
objpointer to the (user-defined part) of an object.
flagsflags from ao2_callback() OBJ_SEARCH_OBJECT - if set, 'obj', is an object. OBJ_SEARCH_KEY - if set, 'obj', is a search key item that is not an object.
Note
This function must be idempotent.
Returns
Computed hash value.

Definition at line 1258 of file astobj2.h.

◆ ao2_prnt_fn

typedef void() ao2_prnt_fn(void *where, const char *fmt,...)

Print output.

Since
12.0.0
Parameters
whereUser data pointer needed to determine where to put output.
fmtprintf type format string.

Definition at line 1435 of file astobj2.h.

◆ ao2_prnt_obj_fn

typedef void() ao2_prnt_obj_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)

Print object key.

Since
12.0.0
Parameters
v_objA pointer to the object we want the key printed.
whereUser data needed by prnt to determine where to put output.
prntPrint output callback function to use.

Definition at line 1445 of file astobj2.h.

◆ ao2_sort_fn

typedef int() ao2_sort_fn(const void *obj_left, const void *obj_right, int flags)

Type of generic container sort function.

Parameters
obj_leftpointer to the (user-defined part) of an object.
obj_rightpointer to the (user-defined part) of an object.
flagsflags from ao2_callback() OBJ_SEARCH_OBJECT - if set, 'obj_right', is an object. OBJ_SEARCH_KEY - if set, 'obj_right', is a search key item that is not an object. OBJ_SEARCH_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
Note
This function must be idempotent.
Return values
negtaiveif obj_left < obj_right
0if obj_left == obj_right
positiveif obj_left > obj_right

Definition at line 1276 of file astobj2.h.

◆ ao2_weakproxy_notification_cb

typedef void(* ao2_weakproxy_notification_cb) (void *weakproxy, void *data)

Definition at line 526 of file astobj2.h.

Enumeration Type Documentation

◆ _cb_results

A callback function will return a combination of CMP_MATCH and CMP_STOP. The latter will terminate the search in a container.

Enumerator
CMP_MATCH 

the object matches the request

CMP_STOP 

stop the search now

Definition at line 1026 of file astobj2.h.

1026 {
1027 CMP_MATCH = 0x1, /*!< the object matches the request */
1028 CMP_STOP = 0x2, /*!< stop the search now */
1029};

◆ ao2_alloc_opts

Options available when allocating an ao2 object.

Enumerator
AO2_ALLOC_OPT_LOCK_MUTEX 

The ao2 object has a recursive mutex lock associated with it.

AO2_ALLOC_OPT_LOCK_RWLOCK 

The ao2 object has a non-recursive read/write lock associated with it.

AO2_ALLOC_OPT_LOCK_NOLOCK 

The ao2 object has no lock associated with it.

AO2_ALLOC_OPT_LOCK_MASK 

The ao2 object locking option field mask.

AO2_ALLOC_OPT_LOCK_OBJ 
AO2_ALLOC_OPT_NO_REF_DEBUG 

The ao2 object will not record any REF_DEBUG entries

Definition at line 361 of file astobj2.h.

361 {
362 /*! The ao2 object has a recursive mutex lock associated with it. */
363 AO2_ALLOC_OPT_LOCK_MUTEX = (0 << 0),
364 /*! The ao2 object has a non-recursive read/write lock associated with it. */
365 AO2_ALLOC_OPT_LOCK_RWLOCK = (1 << 0),
366 /*! The ao2 object has no lock associated with it. */
367 AO2_ALLOC_OPT_LOCK_NOLOCK = (2 << 0),
368 /*! The ao2 object locking option field mask. */
369 AO2_ALLOC_OPT_LOCK_MASK = (3 << 0),
370 /*!
371 * \internal The ao2 object uses a separate object for locking.
372 *
373 * \note This option is used internally by ao2_alloc_with_lockobj and
374 * should never be passed directly to ao2_alloc.
375 */
377 /*! The ao2 object will not record any REF_DEBUG entries */
379};
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
@ AO2_ALLOC_OPT_LOCK_OBJ
Definition astobj2.h:376
@ AO2_ALLOC_OPT_LOCK_RWLOCK
Definition astobj2.h:365
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition astobj2.h:363
@ AO2_ALLOC_OPT_LOCK_MASK
Definition astobj2.h:369
@ AO2_ALLOC_OPT_NO_REF_DEBUG
Definition astobj2.h:378

◆ ao2_container_opts

Options available when allocating an ao2 container object.

Note
Each option is open to some interpretation by the container type as long as it makes sense with the option name.
Enumerator
AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN 

Insert objects at the beginning of the container. (Otherwise it is the opposite; insert at the end.)

Note
If an ao2_sort_fn is provided, the object is inserted before any objects with duplicate keys.
Hash containers insert the object in the computed hash bucket in the indicated manner.
AO2_CONTAINER_ALLOC_OPT_DUPS_MASK 

The ao2 container objects with duplicate keys option field mask.

AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW 

Allow objects with duplicate keys in container.

AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT 

Reject objects with duplicate keys in container.

Note
The container must be sorted. i.e. have an ao2_sort_fn.
AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT 

Reject duplicate objects in container.

Don't link the same object into the container twice. However, you can link a different object with the same key.

Note
The container must be sorted. i.e. have an ao2_sort_fn.
It is assumed that the objects are located where the search key says they should be located.
AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE 

Replace objects with duplicate keys in container.

The existing duplicate object is removed and the new object takes the old object's place.

Note
The container must be sorted. i.e. have an ao2_sort_fn.

Definition at line 1161 of file astobj2.h.

1161 {
1162 /*!
1163 * \brief Insert objects at the beginning of the container.
1164 * (Otherwise it is the opposite; insert at the end.)
1165 *
1166 * \note If an ao2_sort_fn is provided, the object is inserted
1167 * before any objects with duplicate keys.
1168 *
1169 * \note Hash containers insert the object in the computed hash
1170 * bucket in the indicated manner.
1171 */
1173
1174 /*!
1175 * \brief The ao2 container objects with duplicate keys option field mask.
1176 */
1178 /*!
1179 * \brief Allow objects with duplicate keys in container.
1180 */
1182 /*!
1183 * \brief Reject objects with duplicate keys in container.
1184 *
1185 * \note The container must be sorted. i.e. have an
1186 * ao2_sort_fn.
1187 */
1189 /*!
1190 * \brief Reject duplicate objects in container.
1191 *
1192 * \details Don't link the same object into the container twice.
1193 * However, you can link a different object with the same key.
1194 *
1195 * \note The container must be sorted. i.e. have an
1196 * ao2_sort_fn.
1197 *
1198 * \note It is assumed that the objects are located where the
1199 * search key says they should be located.
1200 */
1202 /*!
1203 * \brief Replace objects with duplicate keys in container.
1204 *
1205 * \details The existing duplicate object is removed and the new
1206 * object takes the old object's place.
1207 *
1208 * \note The container must be sorted. i.e. have an
1209 * ao2_sort_fn.
1210 */
1212};

◆ ao2_iterator_flags

Flags that can be passed to ao2_iterator_init() to modify the behavior of the iterator.

Enumerator
AO2_ITERATOR_DONTLOCK 

Assume that the ao2_container is already locked.

Note
For ao2_containers that have mutexes, no locking will be done.
For ao2_containers that have RWLOCKs, the lock will be promoted to write mode as needed. The lock will be returned to the original locked state.
Only use this flag if the ao2_container is manually locked already. You should hold the lock until after ao2_iterator_destroy(). If you must release the lock then you must at least hold the lock whenever you call an ao2_iterator_xxx function with this iterator.
AO2_ITERATOR_MALLOCD 

Indicates that the iterator was dynamically allocated by astobj2 API and should be freed by ao2_iterator_destroy().

AO2_ITERATOR_UNLINK 

Indicates that before the iterator returns an object from the container being iterated, the object should be unlinked from the container.

AO2_ITERATOR_DESCENDING 

Iterate in descending order (Last to first container object) (Otherwise ascending order)

Note
Other traversal orders such as pre-order and post-order do not make sense because they require the container structure to be static during the traversal. Iterators just about guarantee that is not going to happen because the container is allowed to change by other threads during the iteration.

Definition at line 1835 of file astobj2.h.

1835 {
1836 /*!
1837 * \brief Assume that the ao2_container is already locked.
1838 *
1839 * \note For ao2_containers that have mutexes, no locking will
1840 * be done.
1841 *
1842 * \note For ao2_containers that have RWLOCKs, the lock will be
1843 * promoted to write mode as needed. The lock will be returned
1844 * to the original locked state.
1845 *
1846 * \note Only use this flag if the ao2_container is manually
1847 * locked already. You should hold the lock until after
1848 * ao2_iterator_destroy(). If you must release the lock then
1849 * you must at least hold the lock whenever you call an
1850 * ao2_iterator_xxx function with this iterator.
1851 */
1852 AO2_ITERATOR_DONTLOCK = (1 << 0),
1853 /*!
1854 * Indicates that the iterator was dynamically allocated by
1855 * astobj2 API and should be freed by ao2_iterator_destroy().
1856 */
1857 AO2_ITERATOR_MALLOCD = (1 << 1),
1858 /*!
1859 * Indicates that before the iterator returns an object from
1860 * the container being iterated, the object should be unlinked
1861 * from the container.
1862 */
1863 AO2_ITERATOR_UNLINK = (1 << 2),
1864 /*!
1865 * Iterate in descending order (Last to first container object)
1866 * (Otherwise ascending order)
1867 *
1868 * \note Other traversal orders such as pre-order and post-order
1869 * do not make sense because they require the container
1870 * structure to be static during the traversal. Iterators just
1871 * about guarantee that is not going to happen because the
1872 * container is allowed to change by other threads during the
1873 * iteration.
1874 */
1875 AO2_ITERATOR_DESCENDING = (1 << 3),
1876};

◆ ao2_lock_req

Which lock to request.

Enumerator
AO2_LOCK_REQ_MUTEX 

Request the mutex lock be acquired.

AO2_LOCK_REQ_RDLOCK 

Request the read lock be acquired.

AO2_LOCK_REQ_WRLOCK 

Request the write lock be acquired.

Definition at line 700 of file astobj2.h.

700 {
701 /*! Request the mutex lock be acquired. */
703 /*! Request the read lock be acquired. */
705 /*! Request the write lock be acquired. */
707};

◆ search_flags

Flags passed to ao2_callback_fn(), ao2_hash_fn(), and ao2_sort_fn() to modify behaviour.

Enumerator
OBJ_UNLINK 

Unlink the object for which the callback function returned CMP_MATCH.

OBJ_NODATA 

On match, don't return the object hence do not increase its refcount.

OBJ_MULTIPLE 

Don't stop at the first match in ao2_callback() unless the result of the callback function has the CMP_STOP bit set.

OBJ_NOLOCK 

Assume that the ao2_container is already locked.

Note
For ao2_containers that have mutexes, no locking will be done.
For ao2_containers that have RWLOCKs, the lock will be promoted to write mode as needed. The lock will be returned to the original locked state.
Only use this flag if the ao2_container is manually locked already.
OBJ_SEARCH_MASK 

Search option field mask.

Todo:
Eventually OBJ_SEARCH_MASK will shrink to a two bit field when the codebase is made to use the search field values as a field instead of independent bits.
OBJ_SEARCH_NONE 

The arg parameter has no meaning to the astobj2 code.

OBJ_SEARCH_OBJECT 

The arg parameter is an object of the same type.

The arg parameter is an object of the same type as the one being searched for, so use the object's ao2_hash_fn and/or ao2_sort_fn functions for optimized searching.

Note
The supplied ao2_callback_fn is called after the container nodes have been filtered by the ao2_hash_fn and/or ao2_sort_fn functions.
OBJ_SEARCH_KEY 

The arg parameter is a search key, but is not an object.

This can be used when you want to be able to pass custom data to the container's stored ao2_hash_fn, ao2_sort_fn, and ao2_find ao2_callback_fn functions that is not a full object, but perhaps just a string.

Note
The supplied ao2_callback_fn is called after the container nodes have been filtered by the ao2_hash_fn and/or ao2_sort_fn functions.
OBJ_SEARCH_PARTIAL_KEY 

The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.

The partial key can be used by the ao2_sort_fn to guide the search to find a contiguous subset of a sorted container. For example, a sorted container holds: "A", "B", "Bert", "Beth", "Earnie". Doing a partial key search with "B" will find the sorted subset of all held objects starting with "B".

Note
The supplied ao2_callback_fn is called after the container nodes have been filtered by the ao2_sort_fn function.
OBJ_ORDER_MASK 

Traverse order option field mask.

OBJ_ORDER_ASCENDING 

Traverse in ascending order (First to last container object)

OBJ_ORDER_DESCENDING 

Traverse in descending order (Last to first container object)

OBJ_ORDER_PRE 

Traverse in pre-order (Node then children, for tree container)

Note
For non-tree containers, it is up to the container type to make the best interpretation of the order. For list and hash containers, this also means ascending order because a binary tree can degenerate into a list.
OBJ_ORDER_POST 

Traverse in post-order (Children then node, for tree container)

Note
For non-tree containers, it is up to the container type to make the best interpretation of the order. For list and hash containers, this also means descending order because a binary tree can degenerate into a list.

Definition at line 1034 of file astobj2.h.

1034 {
1035 /*!
1036 * Unlink the object for which the callback function returned
1037 * CMP_MATCH.
1038 */
1039 OBJ_UNLINK = (1 << 0),
1040 /*!
1041 * On match, don't return the object hence do not increase its
1042 * refcount.
1043 */
1044 OBJ_NODATA = (1 << 1),
1045 /*!
1046 * Don't stop at the first match in ao2_callback() unless the
1047 * result of the callback function has the CMP_STOP bit set.
1048 */
1049 OBJ_MULTIPLE = (1 << 2),
1050 /*!
1051 * \brief Assume that the ao2_container is already locked.
1052 *
1053 * \note For ao2_containers that have mutexes, no locking will
1054 * be done.
1055 *
1056 * \note For ao2_containers that have RWLOCKs, the lock will be
1057 * promoted to write mode as needed. The lock will be returned
1058 * to the original locked state.
1059 *
1060 * \note Only use this flag if the ao2_container is manually
1061 * locked already.
1062 */
1063 OBJ_NOLOCK = (1 << 4),
1064
1065 /*!
1066 * \brief Search option field mask.
1067 *
1068 * \todo Eventually OBJ_SEARCH_MASK will shrink to a two bit
1069 * field when the codebase is made to use the search field
1070 * values as a field instead of independent bits.
1071 */
1072 OBJ_SEARCH_MASK = (0x07 << 5),
1073 /*! \brief The arg parameter has no meaning to the astobj2 code. */
1074 OBJ_SEARCH_NONE = (0 << 5),
1075 /*!
1076 * \brief The arg parameter is an object of the same type.
1077 *
1078 * \details
1079 * The arg parameter is an object of the same type as the one
1080 * being searched for, so use the object's ao2_hash_fn and/or
1081 * ao2_sort_fn functions for optimized searching.
1082 *
1083 * \note The supplied ao2_callback_fn is called after the
1084 * container nodes have been filtered by the ao2_hash_fn and/or
1085 * ao2_sort_fn functions.
1086 */
1087 OBJ_SEARCH_OBJECT = (1 << 5),
1088 /*!
1089 * \brief The arg parameter is a search key, but is not an object.
1090 *
1091 * \details
1092 * This can be used when you want to be able to pass custom data
1093 * to the container's stored ao2_hash_fn, ao2_sort_fn, and
1094 * ao2_find ao2_callback_fn functions that is not a full object,
1095 * but perhaps just a string.
1096 *
1097 * \note The supplied ao2_callback_fn is called after the
1098 * container nodes have been filtered by the ao2_hash_fn and/or
1099 * ao2_sort_fn functions.
1100 */
1101 OBJ_SEARCH_KEY = (2 << 5),
1102 /*!
1103 * \brief The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
1104 *
1105 * \details
1106 * The partial key can be used by the ao2_sort_fn to guide the
1107 * search to find a contiguous subset of a sorted container.
1108 * For example, a sorted container holds: "A", "B", "Bert",
1109 * "Beth", "Earnie". Doing a partial key search with "B" will
1110 * find the sorted subset of all held objects starting with "B".
1111 *
1112 * \note The supplied ao2_callback_fn is called after the
1113 * container nodes have been filtered by the ao2_sort_fn
1114 * function.
1115 */
1116 OBJ_SEARCH_PARTIAL_KEY = (4 << 5),
1117
1118 /*! \brief Traverse order option field mask. */
1119 OBJ_ORDER_MASK = (0x03 << 8),
1120 /*! \brief Traverse in ascending order (First to last container object) */
1121 OBJ_ORDER_ASCENDING = (0 << 8),
1122 /*! \brief Traverse in descending order (Last to first container object) */
1123 OBJ_ORDER_DESCENDING = (1 << 8),
1124 /*!
1125 * \brief Traverse in pre-order (Node then children, for tree container)
1126 *
1127 * \note For non-tree containers, it is up to the container type
1128 * to make the best interpretation of the order. For list and
1129 * hash containers, this also means ascending order because a
1130 * binary tree can degenerate into a list.
1131 */
1132 OBJ_ORDER_PRE = (2 << 8),
1133 /*!
1134 * \brief Traverse in post-order (Children then node, for tree container)
1135 *
1136 * \note For non-tree containers, it is up to the container type
1137 * to make the best interpretation of the order. For list and
1138 * hash containers, this also means descending order because a
1139 * binary tree can degenerate into a list.
1140 */
1141 OBJ_ORDER_POST = (3 << 8),
1142};

Function Documentation

◆ __ao2_alloc()

void * __ao2_alloc ( size_t  data_size,
ao2_destructor_fn  destructor_fn,
unsigned int  options,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 768 of file astobj2.c.

770{
771 return internal_ao2_alloc(data_size, destructor_fn, options, NULL, tag, file, line, func);
772}
static void * internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, void *lockobj, const char *tag, const char *file, int line, const char *func)
Definition astobj2.c:684
#define NULL
Definition resample.c:96
static struct test_options options

References internal_ao2_alloc(), NULL, and options.

Referenced by __ao2_container_alloc_hash(), __ao2_container_alloc_rbtree(), __ao2_weakproxy_alloc(), __ast_channel_internal_alloc_with_initializers(), __ast_format_cap_alloc(), __ast_named_lock_get(), __ast_sorcery_open(), _moh_class_malloc(), and state_alloc().

◆ __ao2_alloc_with_lockobj()

void * __ao2_alloc_with_lockobj ( size_t  data_size,
ao2_destructor_fn  destructor_fn,
void *  lockobj,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 774 of file astobj2.c.

776{
777 return internal_ao2_alloc(data_size, destructor_fn, AO2_ALLOC_OPT_LOCK_OBJ, lockobj,
778 tag, file, line, func);
779}

References AO2_ALLOC_OPT_LOCK_OBJ, and internal_ao2_alloc().

◆ __ao2_callback()

void * __ao2_callback ( struct ao2_container c,
enum search_flags  flags,
ao2_callback_fn cb_fn,
void *  arg,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 410 of file astobj2_container.c.

413{
414 return internal_ao2_traverse(c, flags, cb_fn, arg, NULL, AO2_CALLBACK_DEFAULT, tag, file, line, func);
415}
static void * internal_ao2_traverse(struct ao2_container *self, enum search_flags flags, void *cb_fn, void *arg, void *data, enum ao2_callback_type type, const char *tag, const char *file, int line, const char *func)

References AO2_CALLBACK_DEFAULT, c, ao2_iterator::flags, internal_ao2_traverse(), and NULL.

Referenced by __ao2_find(), and __ao2_unlink().

◆ __ao2_callback_data()

void * __ao2_callback_data ( struct ao2_container c,
enum search_flags  flags,
ao2_callback_data_fn cb_fn,
void *  arg,
void *  data,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 417 of file astobj2_container.c.

420{
421 return internal_ao2_traverse(c, flags, cb_fn, arg, data, AO2_CALLBACK_WITH_DATA, tag, file, line, func);
422}
@ AO2_CALLBACK_WITH_DATA

References AO2_CALLBACK_WITH_DATA, c, ao2_iterator::flags, and internal_ao2_traverse().

◆ __ao2_cleanup()

void __ao2_cleanup ( void *  obj)

gcc attribute(cleanup()) functions

Note
they must be able to handle NULL parameters because most of the allocation/find functions can fail and we don't want to try to tear down a NULL

Definition at line 677 of file astobj2.c.

678{
679 if (obj) {
680 ao2_ref(obj, -1);
681 }
682}

References ao2_ref.

Referenced by agent_request_exec(), ast_ari_bridges_set_video_source(), bridge_agent_hold_push(), bridge_builtin_set_limits(), bridge_stasis_queue_join_action(), dial_bridge_after_cb(), internal_bridge_after_cb(), native_rtp_bridge_framehook_attach(), parking_set_duration(), and speech_observer_loaded().

◆ __ao2_cleanup_debug()

void __ao2_cleanup_debug ( void *  obj,
const char *  tag,
const char *  file,
int  line,
const char *  function 
)

Definition at line 670 of file astobj2.c.

671{
672 if (obj) {
673 __ao2_ref(obj, -1, tag, file, line, function);
674 }
675}
int __ao2_ref(void *user_data, int delta, const char *tag, const char *file, int line, const char *func)
Definition astobj2.c:498

References __ao2_ref().

◆ __ao2_container_alloc_hash()

struct ao2_container * __ao2_container_alloc_hash ( unsigned int  ao2_options,
unsigned int  container_options,
unsigned int  n_buckets,
ao2_hash_fn hash_fn,
ao2_sort_fn sort_fn,
ao2_callback_fn cmp_fn,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 1067 of file astobj2_hash.c.

1071{
1072 unsigned int num_buckets;
1073 size_t container_size;
1074 struct ao2_container_hash *self;
1075
1076 num_buckets = hash_fn ? n_buckets : 1;
1077 container_size = sizeof(struct ao2_container_hash) + num_buckets * sizeof(struct hash_bucket);
1078
1079 self = __ao2_alloc(container_size, container_destruct, ao2_options,
1080 tag ?: __PRETTY_FUNCTION__, file, line, func);
1081 return hash_ao2_container_init(self, container_options, num_buckets, hash_fn,
1082 sort_fn, cmp_fn);
1083}
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
Definition astobj2.c:768
void container_destruct(void *_c)
static struct ao2_container * hash_ao2_container_init(struct ao2_container_hash *self, unsigned int options, unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
Initialize a hash container with the desired number of buckets.
ao2_hash_fn * hash_fn

References __ao2_alloc(), container_destruct(), hash_ao2_container_init(), ao2_container_hash::hash_fn, and ao2_container_hash::n_buckets.

Referenced by __ao2_container_alloc_list(), and hash_ao2_alloc_empty_clone().

◆ __ao2_container_alloc_list()

struct ao2_container * __ao2_container_alloc_list ( unsigned int  ao2_options,
unsigned int  container_options,
ao2_sort_fn sort_fn,
ao2_callback_fn cmp_fn,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 1085 of file astobj2_hash.c.

1088{
1089 return __ao2_container_alloc_hash(ao2_options, container_options, 1, NULL,
1090 sort_fn, cmp_fn, tag, file, line, func);
1091}
struct ao2_container * __ao2_container_alloc_hash(unsigned int ao2_options, unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn, const char *tag, const char *file, int line, const char *func)

References __ao2_container_alloc_hash(), ao2_container::cmp_fn, NULL, and ao2_container::sort_fn.

◆ __ao2_container_alloc_rbtree()

struct ao2_container * __ao2_container_alloc_rbtree ( unsigned int  ao2_options,
unsigned int  container_options,
ao2_sort_fn sort_fn,
ao2_callback_fn cmp_fn,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 2022 of file astobj2_rbtree.c.

2025{
2026 struct ao2_container_rbtree *self;
2027
2028 if (!sort_fn) {
2029 /* Sanity checks. */
2030 ast_log(__LOG_ERROR, file, line, func, "Missing sort_fn()!\n");
2031 return NULL;
2032 }
2033
2034 self = __ao2_alloc(sizeof(*self), container_destruct, ao2_options,
2035 tag ?: __PRETTY_FUNCTION__, file, line, func);
2036 return rb_ao2_container_init(self, container_options, sort_fn, cmp_fn);
2037}
#define ast_log
Definition astobj2.c:42
static struct ao2_container * rb_ao2_container_init(struct ao2_container_rbtree *self, unsigned int options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
Initialize a rbtree container.
#define __LOG_ERROR

References __ao2_alloc(), __LOG_ERROR, ast_log, container_destruct(), NULL, and rb_ao2_container_init().

Referenced by rb_ao2_alloc_empty_clone().

◆ __ao2_container_clone()

struct ao2_container * __ao2_container_clone ( struct ao2_container orig,
enum search_flags  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 753 of file astobj2_container.c.

754{
755 struct ao2_container *clone;
756 int failed;
757
758 /* Create the clone container with the same properties as the original. */
759 if (!__is_ao2_object(orig, file, line, func)) {
760 return NULL;
761 }
762
763 if (!orig->v_table || !orig->v_table->alloc_empty_clone) {
764 /* Sanity checks. */
765 __ast_assert_failed(0, "invalid container v_table", file, line, func);
766 return NULL;
767 }
768
769 clone = orig->v_table->alloc_empty_clone(orig, tag, file, line, func);
770 if (!clone) {
771 return NULL;
772 }
773
774 /* This test is correct. clone must be locked before calling
775 * ao2_container_dup when the OBJ_NOLOCK flag is set, otherwise
776 * we could have errors in __adjust_lock. */
777 if (flags & OBJ_NOLOCK) {
778 ao2_wrlock(clone);
779 }
780 failed = ao2_container_dup(clone, orig, flags);
781 if (flags & OBJ_NOLOCK) {
782 ao2_unlock(clone);
783 }
784 if (failed) {
785 /* Object copy into the clone container failed. */
786 __ao2_ref(clone, -1, tag ?: "Clone creation failed", file, line, func);
787 clone = NULL;
788 }
789 return clone;
790}
#define ao2_wrlock(a)
Definition astobj2.h:719
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
#define __is_ao2_object(user_data, file, line, func)
ao2_container_alloc_empty_clone_fn alloc_empty_clone
Create an empty copy of this container.
const struct ao2_container_methods * v_table
void DO_CRASH_NORETURN __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)
Definition utils.c:2852

References __ao2_ref(), __ast_assert_failed(), __is_ao2_object, ao2_container_methods::alloc_empty_clone, ao2_container_dup(), ao2_unlock, ao2_wrlock, NULL, OBJ_NOLOCK, and ao2_container::v_table.

◆ __ao2_find()

void * __ao2_find ( struct ao2_container c,
const void *  arg,
enum search_flags  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

the find function just invokes the default callback with some reasonable flags.

Definition at line 427 of file astobj2_container.c.

429{
430 void *arged = (void *) arg;/* Done to avoid compiler const warning */
431
432 if (!c) {
433 /* Sanity checks. */
434 ast_assert(0);
435 return NULL;
436 }
437 return __ao2_callback(c, flags, c->cmp_fn, arged, tag, file, line, func);
438}
void * __ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line, const char *func)
#define ast_assert(a)
Definition utils.h:779

References __ao2_callback(), ast_assert, c, ao2_iterator::flags, and NULL.

Referenced by __ast_format_cache_get(), and _get_mohbyname().

◆ __ao2_get_weakproxy()

void * __ao2_get_weakproxy ( void *  obj,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 917 of file astobj2.c.

918{
919 struct astobj2 *obj_internal = __INTERNAL_OBJ_CHECK(obj, file, line, func);
920
921 if (!obj_internal || obj_internal->priv_data.magic != AO2_MAGIC) {
922 /* This method is meant to be run on normal ao2 objects! */
923 return NULL;
924 }
925
926 if (!obj_internal->priv_data.weakptr) {
927 return NULL;
928 }
929
930 __ao2_ref(obj_internal->priv_data.weakptr, +1, tag, file, line, func);
931 return obj_internal->priv_data.weakptr;
932}
#define __INTERNAL_OBJ_CHECK(user_data, file, line, func)
convert from a pointer _p to a user-defined object
Definition astobj2.c:171
#define AO2_MAGIC
Definition astobj2.c:96
uint32_t magic
Definition astobj2.c:93
void * weakptr
Definition astobj2.c:57
struct __priv_data priv_data
Definition astobj2.c:105

References __ao2_ref(), __INTERNAL_OBJ_CHECK, AO2_MAGIC, __priv_data::magic, NULL, astobj2::priv_data, and __priv_data::weakptr.

◆ __ao2_global_obj_ref()

void * __ao2_global_obj_ref ( struct ao2_global_obj holder,
const char *  tag,
const char *  file,
int  line,
const char *  func,
const char *  name 
)

Definition at line 72 of file astobj2_global.c.

73{
74 void *obj;
75
76 if (!holder) {
77 /* For sanity */
78 ast_log(LOG_ERROR, "Must be called with a global object!\n");
79 ast_assert(0);
80 return NULL;
81 }
82
83 if (__ast_rwlock_rdlock(file, line, func, &holder->lock, name)) {
84 /* Could not get the read lock. */
85 ast_assert(0);
86 return NULL;
87 }
88
89 obj = holder->obj;
90 if (obj) {
91 __ao2_ref(obj, +1, tag, file, line, func);
92 }
93
94 __ast_rwlock_unlock(file, line, func, &holder->lock, name);
95
96 return obj;
97}
#define LOG_ERROR
int __ast_rwlock_unlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
Definition lock.c:782
int __ast_rwlock_rdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
Definition lock.c:853

References __ao2_ref(), __ast_rwlock_rdlock(), __ast_rwlock_unlock(), ast_assert, ast_log, ao2_global_obj::lock, LOG_ERROR, name, NULL, and ao2_global_obj::obj.

◆ __ao2_global_obj_replace()

void * __ao2_global_obj_replace ( struct ao2_global_obj holder,
void *  obj,
const char *  tag,
const char *  file,
int  line,
const char *  func,
const char *  name 
)

Definition at line 33 of file astobj2_global.c.

34{
35 void *obj_old;
36
37 if (!holder) {
38 /* For sanity */
39 ast_log(LOG_ERROR, "Must be called with a global object!\n");
40 ast_assert(0);
41 return NULL;
42 }
43 if (__ast_rwlock_wrlock(file, line, func, &holder->lock, name)) {
44 /* Could not get the write lock. */
45 ast_assert(0);
46 return NULL;
47 }
48
49 if (obj) {
50 __ao2_ref(obj, +1, tag, file, line, func);
51 }
52 obj_old = holder->obj;
53 holder->obj = obj;
54
55 __ast_rwlock_unlock(file, line, func, &holder->lock, name);
56
57 return obj_old;
58}
int __ast_rwlock_wrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
Definition lock.c:957

References __ao2_ref(), __ast_rwlock_unlock(), __ast_rwlock_wrlock(), ast_assert, ast_log, ao2_global_obj::lock, LOG_ERROR, name, NULL, and ao2_global_obj::obj.

Referenced by __ao2_global_obj_replace_unref().

◆ __ao2_global_obj_replace_unref()

int __ao2_global_obj_replace_unref ( struct ao2_global_obj holder,
void *  obj,
const char *  tag,
const char *  file,
int  line,
const char *  func,
const char *  name 
)

Definition at line 60 of file astobj2_global.c.

61{
62 void *obj_old;
63
64 obj_old = __ao2_global_obj_replace(holder, obj, tag, file, line, func, name);
65 if (obj_old) {
66 __ao2_ref(obj_old, -1, tag, file, line, func);
67 return 1;
68 }
69 return 0;
70}
void * __ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)

References __ao2_global_obj_replace(), __ao2_ref(), and name.

◆ __ao2_iterator_next()

void * __ao2_iterator_next ( struct ao2_iterator iter,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 556 of file astobj2_container.c.

558{
559 enum ao2_lock_req orig_lock;
560 struct ao2_container_node *node;
561 void *ret;
562
563 if (!__is_ao2_object(iter->c, file, line, func)) {
564 return NULL;
565 }
566
567 if (!iter->c->v_table || !iter->c->v_table->iterator_next) {
568 /* Sanity checks. */
569 __ast_assert_failed(0, "invalid iterator container v_table", file, line, func);
570 return NULL;
571 }
572
573 if (iter->complete) {
574 /* Don't return any more objects. */
575 return NULL;
576 }
577
578 if (iter->flags & AO2_ITERATOR_DONTLOCK) {
579 if (iter->flags & AO2_ITERATOR_UNLINK) {
580 orig_lock = __adjust_lock(iter->c, AO2_LOCK_REQ_WRLOCK, 1);
581 } else {
582 orig_lock = __adjust_lock(iter->c, AO2_LOCK_REQ_RDLOCK, 1);
583 }
584 } else {
585 orig_lock = AO2_LOCK_REQ_MUTEX;
586 if (iter->flags & AO2_ITERATOR_UNLINK) {
587 ao2_wrlock(iter->c);
588 } else {
589 ao2_rdlock(iter->c);
590 }
591 }
592
593 node = iter->c->v_table->iterator_next(iter->c, iter->last_node, iter->flags);
594 if (node) {
595 ret = node->obj;
596
597 if (iter->flags & AO2_ITERATOR_UNLINK) {
598 /* Transfer the object ref from the container to the returned object. */
600
601 /* Transfer the container's node ref to the iterator. */
602 } else {
603 /* Bump ref of returned object */
604 __ao2_ref(ret, +1, tag ?: "Next iterator object.", file, line, func);
605
606 /* Bump the container's node ref for the iterator. */
607 ao2_ref(node, +1);
608 }
609 } else {
610 /* The iteration has completed. */
611 iter->complete = 1;
612 ret = NULL;
613 }
614
615 /* Replace the iterator's node */
616 if (iter->last_node) {
617 ao2_ref(iter->last_node, -1);
618 }
619 iter->last_node = node;
620
621 if (iter->flags & AO2_ITERATOR_DONTLOCK) {
622 __adjust_lock(iter->c, orig_lock, 0);
623 } else {
624 ao2_unlock(iter->c);
625 }
626
627 return ret;
628}
enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int keep_stronger)
Definition astobj2.c:425
#define ao2_rdlock(a)
Definition astobj2.h:718
int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flags, const char *tag, const char *file, int line, const char *func)
@ AO2_UNLINK_NODE_DEC_COUNT
ao2_iterator_next_fn iterator_next
Generic container node.

References __adjust_lock(), __ao2_ref(), __ast_assert_failed(), __container_unlink_node_debug(), __is_ao2_object, AO2_ITERATOR_DONTLOCK, AO2_ITERATOR_UNLINK, AO2_LOCK_REQ_MUTEX, AO2_LOCK_REQ_RDLOCK, AO2_LOCK_REQ_WRLOCK, ao2_rdlock, ao2_ref, AO2_UNLINK_NODE_DEC_COUNT, ao2_unlock, ao2_wrlock, ao2_iterator::c, ao2_iterator::complete, ao2_iterator::flags, ao2_container_methods::iterator_next, ao2_iterator::last_node, NULL, and ao2_container::v_table.

◆ __ao2_link()

int __ao2_link ( struct ao2_container c,
void *  obj_new,
int  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 94 of file astobj2_container.c.

96{
97 int res;
98 enum ao2_lock_req orig_lock;
100
101 if (!__is_ao2_object(obj_new, file, line, func)
102 || !__is_ao2_object(self, file, line, func)) {
103 return 0;
104 }
105
106 if (!self->v_table || !self->v_table->new_node || !self->v_table->insert) {
107 /* Sanity checks. */
108 __ast_assert_failed(0, "invalid container v_table", file, line, func);
109 return 0;
110 }
111
112 if (flags & OBJ_NOLOCK) {
113 orig_lock = __adjust_lock(self, AO2_LOCK_REQ_WRLOCK, 1);
114 } else {
115 ao2_wrlock(self);
116 orig_lock = AO2_LOCK_REQ_MUTEX;
117 }
118
119 res = 0;
120 node = self->v_table->new_node(self, obj_new, tag, file, line, func);
121 if (node) {
122#if defined(AO2_DEBUG)
123 if (ao2_container_check(self, OBJ_NOLOCK)) {
124 ast_log(LOG_ERROR, "Container integrity failed before insert.\n");
125 }
126#endif /* defined(AO2_DEBUG) */
127
128 /* Insert the new node. */
129 switch (self->v_table->insert(self, node)) {
131 node->is_linked = 1;
132 ast_atomic_fetchadd_int(&self->elements, 1);
133#if defined(AO2_DEBUG)
134 AO2_DEVMODE_STAT(++self->nodes);
135 if (self->v_table->link_stat) {
136 self->v_table->link_stat(self, node);
137 }
138#endif /* defined(AO2_DEBUG) */
139 /* Fall through */
141#if defined(AO2_DEBUG)
142 if (ao2_container_check(self, OBJ_NOLOCK)) {
143 ast_log(LOG_ERROR, "Container integrity failed after insert or replace.\n");
144 }
145#endif /* defined(AO2_DEBUG) */
146 res = 1;
147 break;
149 ao2_ref(node, -1);
150 break;
151 }
152 }
153
154 if (flags & OBJ_NOLOCK) {
155 __adjust_lock(self, orig_lock, 0);
156 } else {
157 ao2_unlock(self);
158 }
159
160 return res;
161}
int ao2_container_check(struct ao2_container *self, enum search_flags flags)
Perform an integrity check on the specified container.
@ AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED
@ AO2_CONTAINER_INSERT_NODE_REJECTED
@ AO2_CONTAINER_INSERT_NODE_INSERTED
#define AO2_DEVMODE_STAT(stat)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition lock.h:764

References __adjust_lock(), __ast_assert_failed(), __is_ao2_object, ao2_container_check(), AO2_CONTAINER_INSERT_NODE_INSERTED, AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED, AO2_CONTAINER_INSERT_NODE_REJECTED, AO2_DEVMODE_STAT, AO2_LOCK_REQ_MUTEX, AO2_LOCK_REQ_WRLOCK, ao2_ref, ao2_unlock, ao2_wrlock, ast_atomic_fetchadd_int(), ast_log, ao2_container::elements, ao2_container_methods::insert, LOG_ERROR, ao2_container_methods::new_node, OBJ_NOLOCK, and ao2_container::v_table.

Referenced by internal_ao2_traverse().

◆ __ao2_lock()

int __ao2_lock ( void *  a,
enum ao2_lock_req  lock_how,
const char *  file,
const char *  func,
int  line,
const char *  var 
)

Lock an object.

Parameters
aA pointer to the object we want to lock.
lock_how,file,func,line,var
Returns
0 on success, other values on error.

Definition at line 222 of file astobj2.c.

223{
224 struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
225 struct astobj2_lock *obj_mutex;
226 struct astobj2_rwlock *obj_rwlock;
227 struct astobj2_lockobj *obj_lockobj;
228 int res = 0;
229
230 if (obj == NULL) {
231 return -1;
232 }
233
234 if (ref_log) {
235 obj->priv_data.lockused = 1;
236 }
237
240 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
241 res = __ast_pthread_mutex_lock(file, line, func, var, &obj_mutex->mutex.lock);
242#ifdef AO2_DEBUG
243 if (!res) {
244 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
245 }
246#endif
247 break;
249 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
250 switch (lock_how) {
253 res = __ast_rwlock_wrlock(file, line, func, &obj_rwlock->rwlock.lock, var);
254 if (!res) {
256#ifdef AO2_DEBUG
257 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
258#endif
259 }
260 break;
262 res = __ast_rwlock_rdlock(file, line, func, &obj_rwlock->rwlock.lock, var);
263 if (!res) {
265#ifdef AO2_DEBUG
266 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
267#endif
268 }
269 break;
270 }
271 break;
273 /* The ao2 object has no lock. */
274 break;
276 obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
277 res = __ao2_lock(obj_lockobj->lockobj.lock, lock_how, file, func, line, var);
278 break;
279 default:
280 ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
281 user_data);
282 return -1;
283 }
284
285 return res;
286}
#define INTERNAL_OBJ_LOCKOBJ(user_data)
Definition astobj2.c:160
static FILE * ref_log
Definition astobj2.c:44
#define INTERNAL_OBJ_MUTEX(user_data)
Definition astobj2.c:154
int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
Lock an object.
Definition astobj2.c:222
#define INTERNAL_OBJ_RWLOCK(user_data)
Definition astobj2.c:157
int __ast_pthread_mutex_lock(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
Definition lock.c:255
uint32_t options
The ao2 object option flags.
Definition astobj2.c:70
uint32_t lockused
Set to 1 when the lock is used if refdebug is enabled.
Definition astobj2.c:77
ast_mutex_t lock
Definition astobj2.c:116
ast_rwlock_t lock
Definition astobj2.c:127
struct ao2_lock_priv mutex
Definition astobj2.c:121
struct ao2_lockobj_priv lockobj
Definition astobj2.c:145
void * user_data[0]
Definition astobj2.c:147
struct ao2_rwlock_priv rwlock
Definition astobj2.c:134
void * user_data[0]
Definition astobj2.c:106

References __ao2_lock(), __ast_pthread_mutex_lock(), __ast_rwlock_rdlock(), __ast_rwlock_wrlock(), __INTERNAL_OBJ_CHECK, __LOG_ERROR, AO2_ALLOC_OPT_LOCK_MASK, AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_NOLOCK, AO2_ALLOC_OPT_LOCK_OBJ, AO2_ALLOC_OPT_LOCK_RWLOCK, AO2_LOCK_REQ_MUTEX, AO2_LOCK_REQ_RDLOCK, AO2_LOCK_REQ_WRLOCK, ast_atomic_fetchadd_int(), ast_log, INTERNAL_OBJ_LOCKOBJ, INTERNAL_OBJ_MUTEX, INTERNAL_OBJ_RWLOCK, ao2_lock_priv::lock, ao2_rwlock_priv::lock, ao2_lockobj_priv::lock, astobj2_lockobj::lockobj, __priv_data::lockused, astobj2_lock::mutex, NULL, ao2_rwlock_priv::num_lockers, __priv_data::options, astobj2::priv_data, ref_log, astobj2_rwlock::rwlock, astobj2::user_data, astobj2_lockobj::user_data, and var.

Referenced by __ao2_lock(), _agent_lock(), _ast_bridge_channel_lock(), and _ast_bridge_lock().

◆ __ao2_ref()

int __ao2_ref ( void *  o,
int  delta,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 498 of file astobj2.c.

500{
501 struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
502 struct astobj2_lock *obj_mutex;
503 struct astobj2_rwlock *obj_rwlock;
504 struct astobj2_lockobj *obj_lockobj;
505 int32_t current_value;
506 int32_t ret;
507 uint32_t privdataoptions;
508 struct ao2_weakproxy *weakproxy = NULL;
509 const char *lock_state;
510
511 if (obj == NULL) {
512 if (ref_log && user_data) {
513 fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**invalid**,%s\n",
514 user_data, delta, ast_get_tid(), file, line, func, tag ?: "");
515 fflush(ref_log);
516 }
517 return -1;
518 }
519
520 /* if delta is 0, just return the refcount */
521 if (delta == 0) {
522 return obj->priv_data.ref_counter;
523 }
524
525 if (delta < 0 && obj->priv_data.magic == AO2_MAGIC && (weakproxy = obj->priv_data.weakptr)) {
526 ao2_lock(weakproxy);
527 }
528
529 /* we modify with an atomic operation the reference counter */
530 ret = ast_atomic_fetch_add(&obj->priv_data.ref_counter, delta, __ATOMIC_RELAXED);
531 current_value = ret + delta;
532
533#ifdef AO2_DEBUG
534 ast_atomic_fetchadd_int(&ao2.total_refs, delta);
535#endif
536
537 if (weakproxy) {
538 struct ao2_weakproxy cbs;
539
540 if (current_value == 1) {
541 /* The only remaining reference is the one owned by the weak object */
542 struct astobj2 *internal_weakproxy;
543
544 internal_weakproxy = INTERNAL_OBJ_CHECK(weakproxy);
545
546 /* Unlink the obj from the weak proxy */
547 internal_weakproxy->priv_data.weakptr = NULL;
548 obj->priv_data.weakptr = NULL;
549
550 /* transfer list to local copy so callbacks are run with weakproxy unlocked. */
551 cbs.destroyed_cb = weakproxy->destroyed_cb;
553
554 /* weak is already unlinked from obj so this won't recurse */
555 ao2_ref(user_data, -1);
556 }
557
558 ao2_unlock(weakproxy);
559
560 if (current_value == 1) {
561 struct ao2_weakproxy_notification *destroyed_cb;
562
563 /* Notify the subscribers that weakproxy now points to NULL. */
564 while ((destroyed_cb = AST_LIST_REMOVE_HEAD(&cbs.destroyed_cb, list))) {
565 destroyed_cb->cb(weakproxy, destroyed_cb->data);
566 ast_free(destroyed_cb);
567 }
568
569 ao2_ref(weakproxy, -1);
570 }
571 }
572
573 if (0 < current_value) {
574 /* The object still lives. */
575#define EXCESSIVE_REF_COUNT 100000
576
577 if (EXCESSIVE_REF_COUNT <= current_value && ret < EXCESSIVE_REF_COUNT) {
578 char excessive_ref_buf[100];
579
580 /* We just reached or went over the excessive ref count trigger */
581 snprintf(excessive_ref_buf, sizeof(excessive_ref_buf),
582 "Excessive refcount %d reached on ao2 object %p",
583 (int)current_value, user_data);
584 ast_log(__LOG_ERROR, file, line, func, "%s\n", excessive_ref_buf);
585
586 __ast_assert_failed(0, excessive_ref_buf, file, line, func);
587 }
588
590 fprintf(ref_log, "%p,%s%d,%d,%s,%d,%s,%d,%s\n", user_data,
591 (delta < 0 ? "" : "+"), delta, ast_get_tid(),
592 file, line, func, (int)ret, tag ?: "");
593 fflush(ref_log);
594 }
595 return ret;
596 }
597
598 /* this case must never happen */
599 if (current_value < 0) {
600 ast_log(__LOG_ERROR, file, line, func,
601 "Invalid refcount %d on ao2 object %p\n", (int)current_value, user_data);
602 if (ref_log) {
603 /* Log to ref_log even if AO2_ALLOC_OPT_NO_REF_DEBUG */
604 fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**invalid**,%s\n",
605 user_data, delta, ast_get_tid(), file, line, func, tag ?: "");
606 fflush(ref_log);
607 }
608 ast_assert(0);
609 /* stop here even if assert doesn't DO_CRASH */
610 return -1;
611 }
612
613 /* last reference, destroy the object */
614 if (obj->priv_data.destructor_fn != NULL) {
615 obj->priv_data.destructor_fn(user_data);
616 }
617
618#ifdef AO2_DEBUG
619 ast_atomic_fetchadd_int(&ao2.total_mem, - obj->priv_data.data_size);
620 ast_atomic_fetchadd_int(&ao2.total_objects, -1);
621#endif
622
623 /* In case someone uses an object after it's been freed */
624 obj->priv_data.magic = 0;
625 /* Save the options locally so the ref_log print at the end doesn't access freed data */
626 privdataoptions = obj->priv_data.options;
627
630 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
631 lock_state = obj->priv_data.lockused ? "used" : "unused";
632 ast_mutex_destroy(&obj_mutex->mutex.lock);
633
634 ast_free(obj_mutex);
635 break;
637 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
638 lock_state = obj->priv_data.lockused ? "used" : "unused";
639 ast_rwlock_destroy(&obj_rwlock->rwlock.lock);
640
641 ast_free(obj_rwlock);
642 break;
644 lock_state = "none";
645 ast_free(obj);
646 break;
648 obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
649 lock_state = obj->priv_data.lockused ? "used" : "unused";
650 ao2_t_ref(obj_lockobj->lockobj.lock, -1, "release lockobj");
651
652 ast_free(obj_lockobj);
653 break;
654 default:
655 ast_log(__LOG_ERROR, file, line, func,
656 "Invalid lock option on ao2 object %p\n", user_data);
657 lock_state = "invalid";
658 break;
659 }
660
661 if (ref_log && !(privdataoptions & AO2_ALLOC_OPT_NO_REF_DEBUG)) {
662 fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**destructor**lock-state:%s**,%s\n",
663 user_data, delta, ast_get_tid(), file, line, func, lock_state, tag ?: "");
664 fflush(ref_log);
665 }
666
667 return ret;
668}
#define ast_free(a)
Definition astmm.h:180
#define EXCESSIVE_REF_COUNT
#define INTERNAL_OBJ_CHECK(user_data)
Definition astobj2.c:183
#define ao2_t_ref(o, delta, tag)
Definition astobj2.h:460
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define ast_rwlock_destroy(rwlock)
Definition lock.h:240
#define ast_mutex_destroy(a)
Definition lock.h:195
#define ast_atomic_fetch_add(ptr, val, memorder)
Support for atomic instructions.
Definition lock.h:676
int32_t ref_counter
Definition astobj2.c:63
ao2_destructor_fn destructor_fn
Definition astobj2.c:55
ao2_weakproxy_notification_cb cb
Definition astobj2.c:110
struct ao2_weakproxy_notification::@321 list
int ast_get_tid(void)
Get current thread ID.
Definition utils.c:2788

References __ast_assert_failed(), __INTERNAL_OBJ_CHECK, __LOG_ERROR, AO2_ALLOC_OPT_LOCK_MASK, AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_NOLOCK, AO2_ALLOC_OPT_LOCK_OBJ, AO2_ALLOC_OPT_LOCK_RWLOCK, AO2_ALLOC_OPT_NO_REF_DEBUG, ao2_lock, AO2_MAGIC, ao2_ref, ao2_t_ref, ao2_unlock, ast_assert, ast_atomic_fetch_add, ast_atomic_fetchadd_int(), ast_free, ast_get_tid(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_REMOVE_HEAD, ast_log, ast_mutex_destroy, ast_rwlock_destroy, ao2_weakproxy_notification::cb, ao2_weakproxy_notification::data, ao2_weakproxy::destroyed_cb, __priv_data::destructor_fn, EXCESSIVE_REF_COUNT, INTERNAL_OBJ_CHECK, INTERNAL_OBJ_LOCKOBJ, INTERNAL_OBJ_MUTEX, INTERNAL_OBJ_RWLOCK, ao2_weakproxy_notification::list, ao2_lock_priv::lock, ao2_rwlock_priv::lock, ao2_lockobj_priv::lock, astobj2_lockobj::lockobj, __priv_data::lockused, __priv_data::magic, astobj2_lock::mutex, NULL, __priv_data::options, astobj2::priv_data, __priv_data::ref_counter, ref_log, astobj2_rwlock::rwlock, astobj2::user_data, and __priv_data::weakptr.

Referenced by __ao2_cleanup_debug(), __ao2_container_clone(), __ao2_get_weakproxy(), __ao2_global_obj_ref(), __ao2_global_obj_replace(), __ao2_global_obj_replace_unref(), __ao2_iterator_next(), __ao2_weakproxy_get_object(), __ao2_weakproxy_ref_object(), __ao2_weakproxy_set_object(), __ast_format_cap_append(), __ast_module_ref(), __ast_module_unref(), __container_unlink_node_debug(), hash_ao2_new_node(), internal_ao2_traverse(), and rb_ao2_new_node().

◆ __ao2_trylock()

int __ao2_trylock ( void *  a,
enum ao2_lock_req  lock_how,
const char *  file,
const char *  func,
int  line,
const char *  var 
)

Try locking– (don't block if fail)

Parameters
aA pointer to the object we want to lock.
lock_how,file,func,line,var
Returns
0 on success, other values on error.

Definition at line 342 of file astobj2.c.

343{
344 struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
345 struct astobj2_lock *obj_mutex;
346 struct astobj2_rwlock *obj_rwlock;
347 struct astobj2_lockobj *obj_lockobj;
348 int res = 0;
349
350 if (obj == NULL) {
351 return -1;
352 }
353
354 if (ref_log) {
355 obj->priv_data.lockused = 1;
356 }
357
360 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
361 res = __ast_pthread_mutex_trylock(file, line, func, var, &obj_mutex->mutex.lock);
362#ifdef AO2_DEBUG
363 if (!res) {
364 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
365 }
366#endif
367 break;
369 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
370 switch (lock_how) {
373 res = __ast_rwlock_trywrlock(file, line, func, &obj_rwlock->rwlock.lock, var);
374 if (!res) {
376#ifdef AO2_DEBUG
377 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
378#endif
379 }
380 break;
382 res = __ast_rwlock_tryrdlock(file, line, func, &obj_rwlock->rwlock.lock, var);
383 if (!res) {
385#ifdef AO2_DEBUG
386 ast_atomic_fetchadd_int(&ao2.total_locked, 1);
387#endif
388 }
389 break;
390 }
391 break;
393 /* The ao2 object has no lock. */
394 return 0;
396 obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
397 res = __ao2_trylock(obj_lockobj->lockobj.lock, lock_how, file, func, line, var);
398 break;
399 default:
400 ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
401 user_data);
402 return -1;
403 }
404
405 return res;
406}
int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
Try locking– (don't block if fail)
Definition astobj2.c:342
int __ast_rwlock_trywrlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
Definition lock.c:1274
int __ast_pthread_mutex_trylock(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
Definition lock.c:398
int __ast_rwlock_tryrdlock(const char *filename, int lineno, const char *func, ast_rwlock_t *t, const char *name)
Definition lock.c:1224

References __ao2_trylock(), __ast_pthread_mutex_trylock(), __ast_rwlock_tryrdlock(), __ast_rwlock_trywrlock(), __INTERNAL_OBJ_CHECK, __LOG_ERROR, AO2_ALLOC_OPT_LOCK_MASK, AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_NOLOCK, AO2_ALLOC_OPT_LOCK_OBJ, AO2_ALLOC_OPT_LOCK_RWLOCK, AO2_LOCK_REQ_MUTEX, AO2_LOCK_REQ_RDLOCK, AO2_LOCK_REQ_WRLOCK, ast_atomic_fetchadd_int(), ast_log, INTERNAL_OBJ_LOCKOBJ, INTERNAL_OBJ_MUTEX, INTERNAL_OBJ_RWLOCK, ao2_lock_priv::lock, ao2_rwlock_priv::lock, ao2_lockobj_priv::lock, astobj2_lockobj::lockobj, __priv_data::lockused, astobj2_lock::mutex, NULL, ao2_rwlock_priv::num_lockers, __priv_data::options, astobj2::priv_data, ref_log, astobj2_rwlock::rwlock, astobj2::user_data, astobj2_lockobj::user_data, and var.

Referenced by __ao2_trylock(), _ast_bridge_channel_trylock(), and _ast_bridge_trylock().

◆ __ao2_unlink()

void * __ao2_unlink ( struct ao2_container c,
void *  obj,
int  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 175 of file astobj2_container.c.

177{
178 if (!__is_ao2_object(user_data, file, line, func)) {
179 /* Sanity checks. */
180 return NULL;
181 }
182
183 flags &= ~OBJ_SEARCH_MASK;
185 __ao2_callback(c, flags, ao2_match_by_addr, user_data, tag, file, line, func);
186
187 return NULL;
188}
int ao2_match_by_addr(void *user_data, void *arg, int flags)
another convenience function is a callback that matches on address

References __ao2_callback(), __is_ao2_object, ao2_match_by_addr(), c, NULL, OBJ_NODATA, OBJ_SEARCH_OBJECT, and OBJ_UNLINK.

◆ __ao2_unlock()

int __ao2_unlock ( void *  a,
const char *  file,
const char *  func,
int  line,
const char *  var 
)

Unlock an object.

Parameters
aA pointer to the object we want unlock.
file,func,line,var
Returns
0 on success, other values on error.

Definition at line 288 of file astobj2.c.

289{
290 struct astobj2 *obj = __INTERNAL_OBJ_CHECK(user_data, file, line, func);
291 struct astobj2_lock *obj_mutex;
292 struct astobj2_rwlock *obj_rwlock;
293 struct astobj2_lockobj *obj_lockobj;
294 int res = 0;
295 int current_value;
296
297 if (obj == NULL) {
298 return -1;
299 }
300
303 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
304 res = __ast_pthread_mutex_unlock(file, line, func, var, &obj_mutex->mutex.lock);
305#ifdef AO2_DEBUG
306 if (!res) {
307 ast_atomic_fetchadd_int(&ao2.total_locked, -1);
308 }
309#endif
310 break;
312 obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
313
314 current_value = ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -1) - 1;
315 if (current_value < 0) {
316 /* It was a WRLOCK that we are unlocking. Fix the count. */
317 ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -current_value);
318 }
319 res = __ast_rwlock_unlock(file, line, func, &obj_rwlock->rwlock.lock, var);
320#ifdef AO2_DEBUG
321 if (!res) {
322 ast_atomic_fetchadd_int(&ao2.total_locked, -1);
323 }
324#endif
325 break;
327 /* The ao2 object has no lock. */
328 break;
330 obj_lockobj = INTERNAL_OBJ_LOCKOBJ(user_data);
331 res = __ao2_unlock(obj_lockobj->lockobj.lock, file, func, line, var);
332 break;
333 default:
334 ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
335 user_data);
336 res = -1;
337 break;
338 }
339 return res;
340}
int __ao2_unlock(void *user_data, const char *file, const char *func, int line, const char *var)
Unlock an object.
Definition astobj2.c:288
int __ast_pthread_mutex_unlock(const char *filename, int lineno, const char *func, const char *mutex_name, ast_mutex_t *t)
Definition lock.c:453

References __ao2_unlock(), __ast_pthread_mutex_unlock(), __ast_rwlock_unlock(), __INTERNAL_OBJ_CHECK, __LOG_ERROR, AO2_ALLOC_OPT_LOCK_MASK, AO2_ALLOC_OPT_LOCK_MUTEX, AO2_ALLOC_OPT_LOCK_NOLOCK, AO2_ALLOC_OPT_LOCK_OBJ, AO2_ALLOC_OPT_LOCK_RWLOCK, ast_atomic_fetchadd_int(), ast_log, INTERNAL_OBJ_LOCKOBJ, INTERNAL_OBJ_MUTEX, INTERNAL_OBJ_RWLOCK, ao2_lock_priv::lock, ao2_rwlock_priv::lock, ao2_lockobj_priv::lock, astobj2_lockobj::lockobj, astobj2_lock::mutex, NULL, ao2_rwlock_priv::num_lockers, __priv_data::options, astobj2::priv_data, astobj2_rwlock::rwlock, astobj2::user_data, astobj2_lockobj::user_data, and var.

Referenced by __ao2_unlock(), _agent_unlock(), _ast_bridge_channel_unlock(), and _ast_bridge_unlock().

◆ __ao2_weakproxy_alloc()

void * __ao2_weakproxy_alloc ( size_t  data_size,
ao2_destructor_fn  destructor_fn,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 793 of file astobj2.c.

795{
796 struct ao2_weakproxy *weakproxy;
797
798 if (data_size < sizeof(*weakproxy)) {
799 ast_assert(0);
800 ast_log(LOG_ERROR, "Requested data_size smaller than minimum.\n");
801 return NULL;
802 }
803
804 weakproxy = __ao2_alloc(data_size, destructor_fn, AO2_ALLOC_OPT_LOCK_MUTEX,
805 tag, file, line, func);
806
807 if (weakproxy) {
808 struct astobj2 *weakproxy_internal;
809
810 /* Just created weakproxy, no need to check if it's valid. */
811 weakproxy_internal = INTERNAL_OBJ(weakproxy);
812 weakproxy_internal->priv_data.magic = AO2_WEAK;
813 }
814
815 return weakproxy;
816}
#define AO2_WEAK
Definition astobj2.c:97
#define INTERNAL_OBJ(user_data)
Definition astobj2.c:163
void * __ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag, const char *file, int line, const char *func)
Definition astobj2.c:768

References __ao2_alloc(), AO2_ALLOC_OPT_LOCK_MUTEX, AO2_WEAK, ast_assert, ast_log, INTERNAL_OBJ, LOG_ERROR, __priv_data::magic, NULL, and astobj2::priv_data.

◆ __ao2_weakproxy_find()

void * __ao2_weakproxy_find ( struct ao2_container c,
const void *  arg,
enum search_flags  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 440 of file astobj2_container.c.

442{
443 void *proxy;
444 void *obj = NULL;
445 enum ao2_lock_req orig_lock;
446
447 ast_assert(!!c);
449 ast_assert(!(flags & ~(OBJ_SEARCH_MASK | OBJ_NOLOCK)));
450
451 if (flags & OBJ_NOLOCK) {
452 orig_lock = __adjust_lock(c, AO2_LOCK_REQ_RDLOCK, 1);
453 } else {
454 orig_lock = AO2_LOCK_REQ_RDLOCK;
455 ao2_rdlock(c);
456 }
457
458 while ((proxy = ao2_find(c, arg, flags | OBJ_NOLOCK))) {
459 obj = __ao2_weakproxy_get_object(proxy, 0, tag ?: __PRETTY_FUNCTION__, file, line, func);
460
461 if (obj) {
462 ao2_ref(proxy, -1);
463 break;
464 }
465
466 /* Upgrade to a write lock */
469 ao2_ref(proxy, -1);
470 }
471
472 if (flags & OBJ_NOLOCK) {
473 /* We'll keep any upgraded lock */
474 __adjust_lock(c, orig_lock, 1);
475 } else {
476 ao2_unlock(c);
477 }
478
479 return obj;
480}
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
Definition astobj2.h:1600
#define ao2_find(container, arg, flags)
Definition astobj2.h:1736

References __adjust_lock(), __ao2_weakproxy_get_object(), ao2_find, AO2_LOCK_REQ_RDLOCK, AO2_LOCK_REQ_WRLOCK, ao2_rdlock, ao2_ref, ao2_unlink_flags, ao2_unlock, ast_assert, c, ao2_iterator::flags, NULL, OBJ_NOLOCK, and OBJ_SEARCH_MASK.

Referenced by __ast_named_lock_get(), and __ast_sorcery_open().

◆ __ao2_weakproxy_get_object()

void * __ao2_weakproxy_get_object ( void *  weakproxy,
int  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 889 of file astobj2.c.

891{
892 struct astobj2 *internal = __INTERNAL_OBJ_CHECK(weakproxy, file, line, func);
893 void *obj;
894
895 if (!internal || internal->priv_data.magic != AO2_WEAK) {
896 /* This method is meant to be run on weakproxy objects! */
897 return NULL;
898 }
899
900 /* We have a weak object, grab reference to object within lock */
901 if (!(flags & OBJ_NOLOCK)) {
902 ao2_lock(weakproxy);
903 }
904
905 obj = internal->priv_data.weakptr;
906 if (obj) {
907 __ao2_ref(obj, +1, tag, file, line, func);
908 }
909
910 if (!(flags & OBJ_NOLOCK)) {
911 ao2_unlock(weakproxy);
912 }
913
914 return obj;
915}

References __ao2_ref(), __INTERNAL_OBJ_CHECK, ao2_lock, ao2_unlock, AO2_WEAK, __priv_data::magic, NULL, OBJ_NOLOCK, astobj2::priv_data, and __priv_data::weakptr.

Referenced by __ao2_weakproxy_find().

◆ __ao2_weakproxy_ref_object()

int __ao2_weakproxy_ref_object ( void *  weakproxy,
int  delta,
int  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 862 of file astobj2.c.

864{
865 struct astobj2 *internal = __INTERNAL_OBJ_CHECK(weakproxy, file, line, func);
866 int ret = -1;
867
868 if (!internal || internal->priv_data.magic != AO2_WEAK) {
869 /* This method is meant to be run on weakproxy objects! */
870 return -2;
871 }
872
873 /* We have a weak object, grab lock. */
874 if (!(flags & OBJ_NOLOCK)) {
875 ao2_lock(weakproxy);
876 }
877
878 if (internal->priv_data.weakptr) {
879 ret = __ao2_ref(internal->priv_data.weakptr, delta, tag, file, line, func);
880 }
881
882 if (!(flags & OBJ_NOLOCK)) {
883 ao2_unlock(weakproxy);
884 }
885
886 return ret;
887}

References __ao2_ref(), __INTERNAL_OBJ_CHECK, ao2_lock, ao2_unlock, AO2_WEAK, __priv_data::magic, OBJ_NOLOCK, astobj2::priv_data, and __priv_data::weakptr.

◆ __ao2_weakproxy_set_object()

int __ao2_weakproxy_set_object ( void *  weakproxy,
void *  obj,
int  flags,
const char *  tag,
const char *  file,
int  line,
const char *  func 
)

Definition at line 818 of file astobj2.c.

820{
821 struct astobj2 *weakproxy_internal = __INTERNAL_OBJ_CHECK(weakproxy, file, line, func);
822 struct astobj2 *obj_internal = __INTERNAL_OBJ_CHECK(obj, file, line, func);
823 int ret = -1;
824
825 if (!weakproxy_internal
826 || weakproxy_internal->priv_data.magic != AO2_WEAK) {
827 return -1;
828 }
829
830 if (!obj_internal
831 || obj_internal->priv_data.weakptr
832 || obj_internal->priv_data.magic != AO2_MAGIC) {
833 return -1;
834 }
835
836 if (!(flags & OBJ_NOLOCK)) {
837 ao2_lock(weakproxy);
838 }
839
840 if (!weakproxy_internal->priv_data.weakptr) {
841 __ao2_ref(obj, +1, tag, file, line, func);
842 __ao2_ref(weakproxy, +1, tag, file, line, func);
843
844 weakproxy_internal->priv_data.weakptr = obj;
845 obj_internal->priv_data.weakptr = weakproxy;
846
847 ret = 0;
848 }
849
850 if (!(flags & OBJ_NOLOCK)) {
851 ao2_unlock(weakproxy);
852 /* It is possible for obj to be accessed now. It's allowed
853 * for weakproxy to already be in a container. Another thread
854 * could have been waiting for a lock on weakproxy to retrieve
855 * the object.
856 */
857 }
858
859 return ret;
860}

References __ao2_ref(), __INTERNAL_OBJ_CHECK, ao2_lock, AO2_MAGIC, ao2_unlock, AO2_WEAK, __priv_data::magic, OBJ_NOLOCK, astobj2::priv_data, and __priv_data::weakptr.

◆ ao2_container_check()

int ao2_container_check ( struct ao2_container self,
enum search_flags  flags 
)

Perform an integrity check on the specified container.

Since
12.0.0
Parameters
selfContainer to check integrity.
flagsOBJ_NOLOCK if a lock is already held on the container.
Return values
0on success.
-1on error.

Definition at line 856 of file astobj2_container.c.

857{
858 int res = 0;
859
860 if (!is_ao2_object(self) || !self->v_table) {
861 /* Sanity checks. */
862 ast_assert(0);
863 return -1;
864 }
865#if defined(AO2_DEBUG)
866 if (!self->v_table->integrity) {
867 /* No integrity check available. Assume container is ok. */
868 return 0;
869 }
870
871 if (!(flags & OBJ_NOLOCK)) {
872 ao2_rdlock(self);
873 }
874 res = self->v_table->integrity(self);
875 if (!(flags & OBJ_NOLOCK)) {
876 ao2_unlock(self);
877 }
878#endif /* defined(AO2_DEBUG) */
879 return res;
880}
#define is_ao2_object(user_data)

References ao2_rdlock, ao2_unlock, ast_assert, is_ao2_object, OBJ_NOLOCK, and ao2_container::v_table.

Referenced by __ao2_link(), AST_TEST_DEFINE(), astobj2_test_1_helper(), hash_ao2_node_destructor(), insert_test_duplicates(), insert_test_vector(), rb_ao2_node_destructor(), and test_container_clone().

◆ ao2_container_count()

int ao2_container_count ( struct ao2_container c)

Returns the number of elements in a container.

return the number of elements in the container

Definition at line 34 of file astobj2_container.c.

35{
36 return ast_atomic_fetchadd_int(&c->elements, 0);
37}

References ast_atomic_fetchadd_int(), and c.

Referenced by action_confbridgekick(), action_confbridgelist(), action_confbridgelistrooms(), action_confbridgesetsinglevideosrc(), action_confbridgestartrecord(), action_confbridgestoprecord(), action_lock_unlock_helper(), action_mute_unmute_helper(), active_channels(), ami_show_aors(), ami_show_auths(), ami_show_contacts(), ami_show_endpoints(), ami_show_resource_lists(), ao2_iterator_count(), app_is_finished(), ari_conf_get_owc_for_app(), ast_ari_applications_list(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), ast_cdr_generic_unregister(), ast_endpoint_snapshot_create(), ast_get_chan_applicationmap(), ast_get_namedgroups(), ast_merge_contexts_and_delete(), ast_namedgroups_intersect(), ast_sip_cli_traverse_objects(), ast_sip_initialize_system(), ast_sip_location_retrieve_first_aor_contact_filtered(), ast_sorcery_create(), ast_sorcery_delete(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_prefix(), ast_sorcery_retrieve_by_regex(), ast_sorcery_update(), ast_srtp_unprotect(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_tone_zone_count(), astobj2_test_1_helper(), auth_observer(), bridges_scrape_cb(), calc_metric(), cc_cli_output_status(), cel_pre_apply_config(), channels_scrape_cb(), check_events(), check_expiration_thread(), cleanup(), cleanup_module(), cli_display_parking_lot(), cli_eprofile_show_all(), cli_fax_show_sessions(), cli_profile_show_all(), cli_show_modules(), cli_show_monitors(), cli_show_tasks(), cli_tn_show_all(), client_config_show_all(), common_identify(), control_command_count(), control_wait(), cpg_confchg_cb(), create_sound_blob(), create_unsolicited_mwi_subscriptions(), device_state_cb(), dial_state_process_bridge_enter(), do_timing(), endelm(), endpoints_scrape_cb(), exten_state_pub_data_alloc(), find_contact(), format_ami_aor_handler(), get_device_state_causing_channels(), global_loaded_observer(), grow(), handle_cli_sound_show(), handle_feature_show(), handle_manager_show_events(), handle_registrations(), handle_show_hint(), handle_show_hints(), insert_test_vector(), ip_identify_apply(), load_common(), locals_show(), member_add_to_queue(), memory_cache_full_update(), memory_cache_populate(), mid_test_sync(), mwi_subscription_established(), native_bridge_is_capable(), native_rtp_bridge_compatible_check(), object_type_loaded_observer(), one_protocol(), outbound_websocket_validate_cb(), parking_lot_remove_if_unused(), pjsip_acf_dial_contacts_read(), presence_state_cb(), print_queue(), pthread_timer_open(), publisher_start(), queue_exec(), queue_function_mem_read(), queued_set_size(), queued_task_pushed(), register_aor_core(), registrar_validate_contacts(), send_unsolicited_mwi_notify(), should_send_event(), shrink(), single_state_process_bridge_enter(), sip_options_apply_aor_configuration(), sip_options_contact_add_task(), sip_options_contact_delete_task(), sip_options_unused_endpoint_state_compositor(), sla_in_use(), smdi_load(), sorcery_memory_cache_create(), sorcery_memory_cache_dump(), sorcery_memory_cache_populate(), sorcery_memory_cache_retrieve_multiple(), sorcery_memory_cache_retrieve_prefix(), sorcery_memory_cache_retrieve_regex(), sorcery_memory_cache_show(), sorcery_object_load(), stale_cache_update(), stasis_app_set_global_debug(), stasis_app_to_cli(), system_create_resolver_and_set_nameservers(), test_ao2_iteration(), test_cel_peer_strings_match(), test_container_clone(), test_sub(), threadpool_send_state_changed(), tps_shutdown(), try_calling(), unload_module(), and xmpp_show_clients().

◆ ao2_container_dump()

void ao2_container_dump ( struct ao2_container self,
enum search_flags  flags,
const char *  name,
void *  where,
ao2_prnt_fn prnt,
ao2_prnt_obj_fn prnt_obj 
)

Display contents of the specified container.

Since
12.0.0
Parameters
selfContainer to dump.
flagsOBJ_NOLOCK if a lock is already held on the container.
nameContainer name. (NULL if anonymous)
whereUser data needed by prnt to determine where to put output.
prntPrint output callback function to use.
prnt_objCallback function to print the given object's key. (NULL if not available)

Definition at line 792 of file astobj2_container.c.

793{
794 if (!is_ao2_object(self) || !self->v_table) {
795 prnt(where, "Invalid container\n");
796 ast_assert(0);
797 return;
798 }
799
800 if (!(flags & OBJ_NOLOCK)) {
801 ao2_rdlock(self);
802 }
803 if (name) {
804 prnt(where, "Container name: %s\n", name);
805 }
806#if defined(AO2_DEBUG)
807 if (self->v_table->dump) {
808 self->v_table->dump(self, where, prnt, prnt_obj);
809 } else
810#endif /* defined(AO2_DEBUG) */
811 {
812 prnt(where, "Container dump not available.\n");
813 }
814 if (!(flags & OBJ_NOLOCK)) {
815 ao2_unlock(self);
816 }
817}

References ao2_rdlock, ao2_unlock, ast_assert, is_ao2_object, name, OBJ_NOLOCK, and ao2_container::v_table.

Referenced by astobj2_test_1_helper(), and test_traversal_sorted().

◆ ao2_container_dup()

int ao2_container_dup ( struct ao2_container dest,
struct ao2_container src,
enum search_flags  flags 
)

Copy all object references in the src container into the dest container.

Since
11.0
Parameters
destContainer to copy src object references into.
srcContainer to copy all object references from.
flagsOBJ_NOLOCK if a lock is already held on both containers. Otherwise, the src container is locked first.
Precondition
The dest container must be empty. If the duplication fails, the dest container will be returned empty.
Note
This can potentially be expensive because a malloc is needed for every object in the src container.
Return values
0on success.
-1on error.

Definition at line 673 of file astobj2_container.c.

674{
675 void *obj;
676 int res = 0;
677
678 if (!(flags & OBJ_NOLOCK)) {
679 ao2_rdlock(src);
680 ao2_wrlock(dest);
681 }
682 obj = ao2_callback(src, OBJ_NOLOCK, dup_obj_cb, dest);
683 if (obj) {
684 /* Failed to put this obj into the dest container. */
685 ao2_t_ref(obj, -1, "Failed to put this object into the dest container.");
686
687 /* Remove all items from the dest container. */
689 NULL);
690 res = -1;
691 }
692 if (!(flags & OBJ_NOLOCK)) {
693 ao2_unlock(dest);
694 ao2_unlock(src);
695 }
696
697 return res;
698}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
static int dup_obj_cb(void *obj, void *arg, int flags)

References ao2_callback, ao2_rdlock, ao2_t_ref, ao2_unlock, ao2_wrlock, dup_obj_cb(), NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_NOLOCK, and OBJ_UNLINK.

Referenced by __ao2_container_clone(), __queues_show(), cli_aor_get_container(), cli_endpoint_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), cli_get_container(), cli_show_monitors(), cli_show_tasks(), cli_unid_get_container(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_config_show_profiles(), handle_cli_sounds_show(), sip_options_apply_aor_configuration(), stasis_show_topics(), tps_report_taskprocessor_list(), and tps_shutdown().

◆ ao2_container_dup_weakproxy_objs()

int ao2_container_dup_weakproxy_objs ( struct ao2_container dest,
struct ao2_container src,
enum search_flags  flags 
)

Copy object references associated with src container weakproxies into the dest container.

Parameters
destContainer to copy src strong object references into.
srcContainer to copy all weak object references from.
flagsOBJ_NOLOCK if a lock is already held on both containers. Otherwise, the src container is locked first.
Precondition
The dest container must be empty. If the duplication fails, the dest container will be returned empty.
Note
This can potentially be expensive because a malloc is needed for every object in the src container.
Every object inside the container is locked by ao2_weakproxy_get_object. Any weakproxy in src with no associated object is ignored.
Return values
0on success.
-1on error.

Definition at line 726 of file astobj2_container.c.

727{
728 void *obj;
729 int res = 0;
730
731 if (!(flags & OBJ_NOLOCK)) {
732 ao2_rdlock(src);
733 ao2_wrlock(dest);
734 }
735 obj = ao2_callback(src, OBJ_NOLOCK, dup_weakproxy_cb, dest);
736 if (obj) {
737 /* Failed to put this obj into the dest container. */
738 ao2_t_ref(obj, -1, "Failed to put this object into the dest container.");
739
740 /* Remove all items from the dest container. */
742 NULL);
743 res = -1;
744 }
745 if (!(flags & OBJ_NOLOCK)) {
746 ao2_unlock(dest);
747 ao2_unlock(src);
748 }
749
750 return res;
751}
static int dup_weakproxy_cb(void *proxy, void *arg, int flags)
Copy obj associated with a weakproxy into the arg container.

References ao2_callback, ao2_rdlock, ao2_t_ref, ao2_unlock, ao2_wrlock, dup_weakproxy_cb(), NULL, OBJ_MULTIPLE, OBJ_NODATA, OBJ_NOLOCK, and OBJ_UNLINK.

Referenced by AST_TEST_DEFINE().

◆ ao2_container_register()

int ao2_container_register ( const char *  name,
struct ao2_container self,
ao2_prnt_obj_fn prnt_obj 
)

Register a container for CLI stats and integrity check.

Since
12.0.0
Parameters
nameName to register the container under.
selfContainer to register.
prnt_objCallback function to print the given object's key. (NULL if not available)
Return values
0on success.
-1on error.

Definition at line 958 of file astobj2_container.c.

959{
960 int res = 0;
961#if defined(AO2_DEBUG)
962 struct ao2_reg_container *reg;
963
964 reg = ao2_t_alloc_options(sizeof(*reg) + strlen(name), ao2_reg_destructor,
965 AO2_ALLOC_OPT_LOCK_NOLOCK, "Container registration object.");
966 if (!reg) {
967 return -1;
968 }
969
970 /* Fill in registered entry */
971 ao2_t_ref(self, +1, "Registering container.");
972 reg->registered = self;
973 reg->prnt_obj = prnt_obj;
974 strcpy(reg->name, name);/* safe */
975
976 if (!ao2_t_link(reg_containers, reg, "Save registration object.")) {
977 res = -1;
978 }
979
980 ao2_t_ref(reg, -1, "Done registering container.");
981#endif /* defined(AO2_DEBUG) */
982 return res;
983}
#define ao2_t_link(container, obj, tag)
Definition astobj2.h:1534
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
Definition astobj2.h:402

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_t_alloc_options, ao2_t_link, ao2_t_ref, and name.

Referenced by ast_bridging_init(), ast_pbx_init(), get_instance(), load_module(), load_module(), stasis_caching_topic_create(), stasis_state_manager_create(), and stasis_topic_pool_create().

◆ ao2_container_stats()

void ao2_container_stats ( struct ao2_container self,
enum search_flags  flags,
const char *  name,
void *  where,
ao2_prnt_fn prnt 
)

Display statistics of the specified container.

Since
12.0.0
Parameters
selfContainer to display statistics.
flagsOBJ_NOLOCK if a lock is already held on the container.
nameContainer name. (NULL if anonymous)
whereUser data needed by prnt to determine where to put output.
prntPrint output callback function to use.

Definition at line 819 of file astobj2_container.c.

820{
821 if (!is_ao2_object(self) || !self->v_table) {
822 prnt(where, "Invalid container\n");
823 ast_assert(0);
824 return;
825 }
826
827 if (!(flags & OBJ_NOLOCK)) {
828 ao2_rdlock(self);
829 }
830 if (name) {
831 prnt(where, "Container name: %s\n", name);
832 }
833 prnt(where, "Number of objects: %d\n", self->elements);
834#if defined(AO2_DEBUG)
835 prnt(where, "Number of nodes: %d\n", self->nodes);
836 prnt(where, "Number of empty nodes: %d\n", self->nodes - self->elements);
837 /*
838 * XXX
839 * If the max_empty_nodes count gets out of single digits you
840 * likely have a code path where ao2_iterator_destroy() is not
841 * called.
842 *
843 * Empty nodes do not harm the container but they do make
844 * container operations less efficient.
845 */
846 prnt(where, "Maximum empty nodes: %d\n", self->max_empty_nodes);
847 if (self->v_table->stats) {
848 self->v_table->stats(self, where, prnt);
849 }
850#endif /* defined(AO2_DEBUG) */
851 if (!(flags & OBJ_NOLOCK)) {
852 ao2_unlock(self);
853 }
854}

References ao2_rdlock, ao2_unlock, ast_assert, ao2_container::elements, is_ao2_object, name, OBJ_NOLOCK, and ao2_container::v_table.

Referenced by astobj2_test_1_helper(), and test_traversal_sorted().

◆ ao2_container_unregister()

void ao2_container_unregister ( const char *  name)

Unregister a container for CLI stats and integrity check.

Since
12.0.0
Parameters
nameName the container is registered under.

Definition at line 985 of file astobj2_container.c.

986{
987#if defined(AO2_DEBUG)
989 "Unregister container");
990#endif /* defined(AO2_DEBUG) */
991}
#define ao2_t_find(container, arg, flags, tag)
Definition astobj2.h:1734

References ao2_t_find, name, OBJ_NODATA, OBJ_SEARCH_KEY, and OBJ_UNLINK.

Referenced by bridge_cleanup(), cdr_engine_shutdown(), close_instance(), load_module(), pbx_shutdown(), stasis_caching_topic_dtor(), state_manager_dtor(), topic_pool_dtor(), and unload_module().

◆ ao2_iterator_cleanup()

void ao2_iterator_cleanup ( struct ao2_iterator iter)

Definition at line 549 of file astobj2_container.c.

550{
551 if (iter) {
553 }
554}
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.

References ao2_iterator_destroy().

Referenced by AST_TEST_DEFINE(), and stasis_app_set_global_debug().

◆ ao2_iterator_count()

int ao2_iterator_count ( struct ao2_iterator iter)

Get a count of the iterated container objects.

Parameters
iterthe iterator to query
Returns
The number of objects in the iterated container

Definition at line 630 of file astobj2_container.c.

631{
632 return ao2_container_count(iter->c);
633}
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.

References ao2_container_count(), and ao2_iterator::c.

◆ ao2_iterator_destroy()

void ao2_iterator_destroy ( struct ao2_iterator iter)

Destroy a container iterator.

Parameters
iterthe iterator to destroy

This function will release the container reference held by the iterator and any other resources it may be holding.

Examples
app_skel.c.

Definition at line 534 of file astobj2_container.c.

535{
536 /* Release any last container node reference. */
538
539 /* Release the iterated container reference. */
540 ao2_t_ref(iter->c, -1, "Unref iterator in ao2_iterator_destroy");
541 iter->c = NULL;
542
543 /* Free the malloced iterator. */
544 if (iter->flags & AO2_ITERATOR_MALLOCD) {
545 ast_free(iter);
546 }
547}
void ao2_iterator_restart(struct ao2_iterator *iter)
Restart an iteration.

References AO2_ITERATOR_MALLOCD, ao2_iterator_restart(), ao2_t_ref, ast_free, ao2_iterator::c, ao2_iterator::flags, and NULL.

Referenced by __iax2_show_peers(), __manager_event_sessions_va(), __queues_show(), __test_cel_generate_peer_str(), aco_set_defaults(), action_agents(), action_confbridgelistrooms(), action_coreshowchannelmap(), action_coreshowchannels(), action_devicestatelist(), action_extensionstatelist(), action_meetmelist(), action_presencestatelist(), add_ice_to_stream(), aeap_tab_complete_name(), agent_show_requested(), agents_post_apply_config(), agents_sweep(), alias_show(), ami_show_registration_contact_statuses(), ao2_iterator_cleanup(), app_to_json(), ari_conf_get_owc_for_app(), ari_show_apps(), ast_add_hint(), ast_ari_bridges_list(), ast_ari_channels_list(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_recordings_list_stored(), ast_bridge_channel_kick(), ast_bucket_file_json(), ast_bucket_json(), ast_cdr_setvar(), ast_channel_dialed_causes_find(), ast_channel_dialed_causes_find_multiple(), ast_complete_channels(), ast_endpoint_snapshot_create(), ast_format_cache_get_by_codec(), ast_merge_contexts_and_delete(), ast_msg_var_iterator_destroy(), ast_multi_channel_blob_get_channels(), ast_pickup_find_by_group(), ast_print_namedgroups(), ast_refer_var_iterator_destroy(), ast_sip_destroy_scheduler(), ast_sip_for_each_contact(), ast_sorcery_objectset_create2(), ast_sorcery_objectset_json_create(), ast_srtp_unprotect(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_var_indications(), ast_var_indications_table(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), astobj2_test_1_helper(), auth_observer(), authenticate(), authenticate_reply(), bridge_app_subscribed_involved(), bridge_channel_event_join_leave(), bridge_channel_moving(), bridge_channel_talking(), bridges_scrape_cb(), build_cli_notify(), calendar_query_exec(), cel_generate_peer_str(), channels_scrape_cb(), check_access(), check_events(), clear_queue(), clear_stats(), cli_complete_endpoint(), cli_complete_notify(), cli_complete_registration(), cli_complete_show(), cli_complete_uri(), cli_console_active(), cli_display_named_acl_list(), cli_fax_show_sessions(), cli_list_devices(), cli_show_channels(), cli_show_modules(), cli_show_monitors(), cli_show_tasks(), cli_tps_reset_stats_all(), compare_weight(), complete_app(), complete_bridge_profile_name(), complete_confbridge_name(), complete_config_module(), complete_core_id(), complete_core_show_hint(), complete_country(), complete_iax2_peers(), complete_iax2_unregister(), complete_menu_name(), complete_mohclass_realtime(), complete_queue(), complete_queue_remove_member(), complete_session(), complete_show_sorcery_object(), complete_sorcery_object(), complete_user_profile_name(), complete_userno(), conf_queue_dtmf(), config_hook_exec(), config_object_tab_complete_name(), configure_parking_extensions(), container_to_json_array(), control_dispatch_all(), control_flush_queue(), control_prestart_dispatch_all(), coreshowchannelmap_add_connected_channels(), destroy_pvts(), device_state_cb(), device_state_cb(), device_state_notify_callbacks(), dial_state_process_bridge_enter(), dialgroup_read(), disable_marked_lots(), dump_queue_members(), endpoints_scrape_cb(), exten_state_publisher_state_cb(), extension_state_cb(), fax_session_tab_complete(), find_contact(), find_queue_by_name_rt(), find_ringing_channel(), find_session(), find_session_by_nonce(), free_members(), generate_or_link_lots_to_configs(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_config_show_profiles(), get_device_state_causing_channels(), get_member_status(), get_transferee(), get_udp_transport(), get_write_timeout(), handle_bridge_pairings(), handle_bridge_show_all(), handle_chanlist(), handle_cli_confbridge_list(), handle_cli_confbridge_show_bridge_profiles(), handle_cli_confbridge_show_menus(), handle_cli_confbridge_show_user_profiles(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_users(), handle_cli_indication_show(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_moh_unregister_class(), handle_cli_odbc_show(), handle_cli_sound_show(), handle_cli_status(), handle_export_primitives(), handle_kickmanconn(), handle_manager_show_event(), handle_manager_show_events(), handle_show_calendar(), handle_show_calendars(), handle_show_hint(), handle_show_hints(), handle_show_named_acl_cmd(), handle_showmanconn(), handle_skel_show_games(), handle_skel_show_levels(), handle_voicemail_show_aliases(), hangupcause_read(), has_mwi_subscription(), iax2_getpeername(), iax2_getpeertrunk(), interface_exists(), ip_identify_apply(), is_longest_waiting_caller(), iterator_destroy(), jingle_add_google_candidates_to_transport(), jingle_add_ice_udp_candidates_to_transport(), jingle_request(), keepalive_transport_thread(), kill_duplicate_offers(), load_users(), local_devicestate(), locals_show(), manager_fax_sessions(), manager_iax2_show_peer_list(), manager_parking_status_all_lots(), manager_parking_status_single_lot(), manager_queues_status(), manager_queues_summary(), mark_lots_as_disabled(), media_cache_handle_show_item(), meetme_menu_admin_extended(), meetme_show_cmd(), moh_rescan_files(), msg_func_write(), mwi_contact_deleted(), mwi_initial_events(), mwi_mailbox_delete_all(), mwi_mailbox_get(), mwi_subscription_mailboxes_str(), num_available_members(), outbound_sessions_load(), outbound_websocket_validate_cb(), parking_lot_get_space(), pjsip_acf_dial_contacts_read(), pjsip_aor_function_read(), poke_all_peers(), pp_each_user_helper(), presence_state_cb(), presence_state_notify_callbacks(), print_queue(), prune_peers(), prune_users(), purge_sessions(), queue_function_mem_read(), queue_function_queuememberlist(), queue_mwi_event(), qupd_exec(), reload(), reload(), reload_single_queue(), remove_all_configured_parking_lot_extensions(), remove_pending_parking_lot_extensions(), rt_handle_member_record(), session_find_by_app(), set_member_paused(), set_member_value(), set_transfer_variables_all(), show_codecs(), single_state_process_bridge_enter(), sip_options_apply_aor_configuration(), sip_options_cleanup_task(), sip_options_endpoint_unlink_aor_feeders(), sip_options_get_endpoint_state_compositor_state(), sip_outbound_publish_synchronize(), sla_calc_station_delays(), sla_change_trunk_state(), sla_queue_event_conf(), sla_show_stations(), sla_show_trunks(), sorcery_memory_cache_complete_name(), sorcery_memory_cache_complete_object_name(), stasis_app_mailboxes_to_json(), stasis_app_to_cli(), stasis_show_topics(), stop_streams(), system_create_resolver_and_set_nameservers(), test_ao2_callback_traversal(), test_ao2_iteration(), test_container_clone(), test_expected_duplicates(), topic_complete_name(), tps_report_taskprocessor_list(), tps_taskprocessor_tab_complete(), transport_state_do_reg_callbacks(), try_calling(), unbound_config_preapply(), update_queue(), update_realtime_members(), xmpp_pubsub_create_affiliations(), xmpp_show_buddies(), and xmpp_show_clients().

◆ ao2_iterator_init()

struct ao2_iterator ao2_iterator_init ( struct ao2_container c,
int  flags 
)

Create an iterator for a container.

Parameters
cthe container
flagsone or more flags from ao2_iterator_flags.
Returns
the constructed iterator
Note
This function does not take a pointer to an iterator; rather, it returns an iterator structure that should be assigned to (overwriting) an existing iterator structure allocated on the stack or on the heap.

This function will take a reference on the container being iterated.

initialize an iterator so we start from the first object

Examples
app_skel.c.

Definition at line 485 of file astobj2_container.c.

486{
487 struct ao2_iterator a = {
488 .c = c,
489 .flags = flags
490 };
491
492 ao2_t_ref(c, +1, "Init iterator with container.");
493
494 return a;
495}

References a, ao2_t_ref, c, and ao2_iterator::flags.

Referenced by __iax2_show_peers(), __manager_event_sessions_va(), __queues_show(), __test_cel_generate_peer_str(), aco_set_defaults(), action_agents(), action_confbridgelistrooms(), action_coreshowchannelmap(), action_coreshowchannels(), action_devicestatelist(), action_extensionstatelist(), action_meetmelist(), action_presencestatelist(), add_ice_to_stream(), aeap_tab_complete_name(), agent_show_requested(), agents_post_apply_config(), alias_show(), ami_show_registration_contact_statuses(), app_to_json(), ari_conf_get_owc_for_app(), ari_show_apps(), ast_add_hint(), ast_ari_bridges_list(), ast_ari_channels_list(), ast_ari_endpoints_list(), ast_ari_endpoints_list_by_tech(), ast_ari_recordings_list_stored(), ast_bridge_channel_kick(), ast_bucket_file_json(), ast_bucket_json(), ast_channel_dialed_causes_find(), ast_complete_channels(), ast_endpoint_snapshot_create(), ast_format_cache_get_by_codec(), ast_merge_contexts_and_delete(), ast_msg_var_iterator_init(), ast_pickup_find_by_group(), ast_print_namedgroups(), ast_refer_var_iterator_init(), ast_sip_destroy_scheduler(), ast_sip_for_each_contact(), ast_sorcery_objectset_create2(), ast_sorcery_objectset_json_create(), ast_srtp_unprotect(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), ast_tone_zone_iterator_init(), astman_verify_session_readpermissions(), astman_verify_session_writepermissions(), astobj2_test_1_helper(), auth_observer(), authenticate(), authenticate_reply(), bridge_app_subscribed_involved(), bridge_channel_event_join_leave(), bridge_channel_moving(), bridge_channel_talking(), bridges_scrape_cb(), build_cli_notify(), calendar_query_exec(), cel_generate_peer_str(), channels_scrape_cb(), check_access(), check_events(), clear_queue(), clear_stats(), cli_complete_endpoint(), cli_complete_notify(), cli_complete_registration(), cli_complete_show(), cli_complete_uri(), cli_console_active(), cli_display_named_acl_list(), cli_fax_show_sessions(), cli_list_devices(), cli_show_channels(), cli_show_modules(), cli_show_monitors(), cli_show_tasks(), cli_tps_reset_stats_all(), compare_weight(), complete_app(), complete_bridge_profile_name(), complete_confbridge_name(), complete_config_module(), complete_core_id(), complete_core_show_hint(), complete_country(), complete_iax2_peers(), complete_iax2_unregister(), complete_menu_name(), complete_mohclass_realtime(), complete_queue(), complete_queue_remove_member(), complete_session(), complete_show_sorcery_object(), complete_sorcery_object(), complete_user_profile_name(), complete_userno(), conf_queue_dtmf(), config_hook_exec(), config_object_tab_complete_name(), configure_parking_extensions(), container_to_json_array(), control_dispatch_all(), control_flush_queue(), control_prestart_dispatch_all(), coreshowchannelmap_add_connected_channels(), destroy_pvts(), device_state_cb(), device_state_cb(), device_state_notify_callbacks(), dial_state_process_bridge_enter(), dialgroup_read(), disable_marked_lots(), dump_queue_members(), endpoints_scrape_cb(), exten_state_publisher_state_cb(), extension_state_cb(), fax_session_tab_complete(), find_contact(), find_queue_by_name_rt(), find_ringing_channel(), find_session(), find_session_by_nonce(), free_members(), generate_or_link_lots_to_configs(), geoloc_config_list_locations(), geoloc_config_list_profiles(), geoloc_config_show_profiles(), get_device_state_causing_channels(), get_member_status(), get_transferee(), get_udp_transport(), get_write_timeout(), handle_bridge_pairings(), handle_bridge_show_all(), handle_chanlist(), handle_cli_confbridge_list(), handle_cli_confbridge_show_bridge_profiles(), handle_cli_confbridge_show_menus(), handle_cli_confbridge_show_user_profiles(), handle_cli_iax2_show_callno_limits(), handle_cli_iax2_show_users(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_cli_moh_unregister_class(), handle_cli_odbc_show(), handle_cli_sound_show(), handle_cli_status(), handle_export_primitives(), handle_kickmanconn(), handle_manager_show_event(), handle_show_calendar(), handle_show_calendars(), handle_show_hint(), handle_show_hints(), handle_show_named_acl_cmd(), handle_showmanconn(), handle_skel_show_games(), handle_skel_show_levels(), handle_voicemail_show_aliases(), iax2_getpeername(), iax2_getpeertrunk(), interface_exists(), internal_ao2_traverse(), ip_identify_apply(), is_longest_waiting_caller(), iterator_all_new(), jingle_add_google_candidates_to_transport(), jingle_add_ice_udp_candidates_to_transport(), jingle_request(), keepalive_transport_thread(), load_users(), local_devicestate(), locals_show(), manager_fax_sessions(), manager_iax2_show_peer_list(), manager_parking_status_all_lots(), manager_parking_status_single_lot(), manager_queues_status(), manager_queues_summary(), mark_lots_as_disabled(), media_cache_handle_show_item(), meetme_menu_admin_extended(), meetme_show_cmd(), moh_rescan_files(), msg_func_write(), mwi_initial_events(), mwi_mailbox_delete_all(), mwi_mailbox_get(), mwi_subscription_mailboxes_str(), num_available_members(), outbound_sessions_load(), outbound_websocket_validate_cb(), parking_lot_get_space(), pjsip_acf_dial_contacts_read(), pjsip_aor_function_read(), poke_all_peers(), pp_each_user_helper(), presence_state_notify_callbacks(), print_queue(), prune_peers(), prune_users(), purge_sessions(), queue_function_mem_read(), queue_function_queuememberlist(), qupd_exec(), reload(), reload(), reload_single_queue(), remove_all_configured_parking_lot_extensions(), remove_pending_parking_lot_extensions(), rt_handle_member_record(), session_find_by_app(), set_member_paused(), set_member_value(), set_transfer_variables_all(), show_codecs(), single_state_process_bridge_enter(), sip_options_apply_aor_configuration(), sip_options_cleanup_task(), sip_options_endpoint_unlink_aor_feeders(), sip_options_get_endpoint_state_compositor_state(), sip_outbound_publish_synchronize(), sla_calc_station_delays(), sla_change_trunk_state(), sla_queue_event_conf(), sla_show_stations(), sla_show_trunks(), sorcery_memory_cache_complete_name(), sorcery_memory_cache_complete_object_name(), stasis_app_mailboxes_to_json(), stasis_app_set_global_debug(), stasis_show_topics(), stop_streams(), system_create_resolver_and_set_nameservers(), test_ao2_iteration(), test_container_clone(), topic_complete_name(), tps_report_taskprocessor_list(), tps_shutdown(), tps_taskprocessor_tab_complete(), try_calling(), unbound_config_preapply(), update_queue(), update_realtime_members(), xmpp_pubsub_create_affiliations(), xmpp_show_buddies(), and xmpp_show_clients().

◆ ao2_iterator_restart()

void ao2_iterator_restart ( struct ao2_iterator iter)

Restart an iteration.

Parameters
iterthe iterator to restart
Note
A restart is not going to have any effect if the iterator was created with the AO2_ITERATOR_UNLINK flag. Any previous objects returned were removed from the container.

Definition at line 497 of file astobj2_container.c.

498{
499 if (!is_ao2_object(iter->c)) {
500 /* Sanity check. */
501 return;
502 }
503
504 /* Release the last container node reference if we have one. */
505 if (iter->last_node) {
506 enum ao2_lock_req orig_lock;
507
508 /*
509 * Do a read lock in case the container node unref does not
510 * destroy the node. If the container node is destroyed then
511 * the lock will be upgraded to a write lock.
512 */
513 if (iter->flags & AO2_ITERATOR_DONTLOCK) {
514 orig_lock = __adjust_lock(iter->c, AO2_LOCK_REQ_RDLOCK, 1);
515 } else {
516 orig_lock = AO2_LOCK_REQ_MUTEX;
517 ao2_rdlock(iter->c);
518 }
519
520 ao2_ref(iter->last_node, -1);
521 iter->last_node = NULL;
522
523 if (iter->flags & AO2_ITERATOR_DONTLOCK) {
524 __adjust_lock(iter->c, orig_lock, 0);
525 } else {
526 ao2_unlock(iter->c);
527 }
528 }
529
530 /* The iteration is no longer complete. */
531 iter->complete = 0;
532}

References __adjust_lock(), AO2_ITERATOR_DONTLOCK, AO2_LOCK_REQ_MUTEX, AO2_LOCK_REQ_RDLOCK, ao2_rdlock, ao2_ref, ao2_unlock, ao2_iterator::c, ao2_iterator::complete, ao2_iterator::flags, is_ao2_object, ao2_iterator::last_node, and NULL.

Referenced by ao2_iterator_destroy().

◆ ao2_match_by_addr()

int ao2_match_by_addr ( void *  user_data,
void *  arg,
int  flags 
)

A common ao2_callback is one that matches by address.

A common ao2_callback is one that matches by address.

Definition at line 166 of file astobj2_container.c.

167{
168 return (user_data == arg) ? (CMP_MATCH | CMP_STOP) : 0;
169}

References CMP_MATCH, and CMP_STOP.

Referenced by __ao2_unlink(), load_module(), and test_container_clone().

◆ ao2_object_get_lockaddr()

void * ao2_object_get_lockaddr ( void *  obj)

Return the mutex lock address of an object.

Parameters
[in]objA pointer to the object we want.
Returns
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 lock address, this allows you to correlate against object address, to match objects to reported locks.

Warning
AO2 lock objects do not include tracking fields when DEBUG_THREADS is not enabled.
Since
1.6.1

Definition at line 476 of file astobj2.c.

477{
478 struct astobj2 *obj;
479 struct astobj2_lock *obj_mutex;
480
482
483 if (obj == NULL) {
484 return NULL;
485 }
486
489 obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
490 return &obj_mutex->mutex.lock;
491 default:
492 break;
493 }
494
495 return NULL;
496}
void * user_data[0]
Definition astobj2.c:123

References AO2_ALLOC_OPT_LOCK_MASK, AO2_ALLOC_OPT_LOCK_MUTEX, INTERNAL_OBJ_CHECK, INTERNAL_OBJ_MUTEX, ao2_lock_priv::lock, astobj2_lock::mutex, NULL, __priv_data::options, astobj2::priv_data, and astobj2_lock::user_data.

Referenced by ast_serializer_shutdown_group_join(), ast_sip_session_suspend(), bridge_channel_wait(), bridge_manager_thread(), consumer_should_stay(), consumer_wait_for(), consumer_wait_for(), consumer_wait_for_completion(), control_wait(), db_sync_thread(), pbx_outgoing_attempt(), rtp_deallocate_transport(), sip_session_suspend_task(), stasis_subscription_join(), transaction_wait(), and wait_for_stimulus().

◆ ao2_options_get()

unsigned int ao2_options_get ( void *  obj)

Retrieve the ao2 options used to create the object.

Parameters
objpointer to the (user-defined part) of an object.
Returns
options from enum ao2_alloc_opts.

Definition at line 781 of file astobj2.c.

782{
783 struct astobj2 *orig_obj;
784
785 orig_obj = INTERNAL_OBJ_CHECK(obj);
786 if (!orig_obj) {
787 return 0;
788 }
789 return orig_obj->priv_data.options;
790}

References INTERNAL_OBJ_CHECK, __priv_data::options, and astobj2::priv_data.

Referenced by __ast_named_lock_get(), hash_ao2_alloc_empty_clone(), and rb_ao2_alloc_empty_clone().

◆ ao2_ref_and_lock()

int ao2_ref_and_lock ( void *  obj)
inline

Increment reference count on an object and lock it.

Since
13.9.0
Parameters
[in]objA pointer to the ao2 object
Return values
0The object is not an ao2 object or wasn't locked successfully
1The object's reference count was incremented and was locked

Definition at line 780 of file astobj2.h.

References ao2_ref, and ao2_unlock.

◆ ao2_unlock_and_unref()

int ao2_unlock_and_unref ( void *  obj)
inline

Unlock an object and decrement its reference count.

Since
13.9.0
Parameters
[in]objA pointer to the ao2 object
Return values
0The object is not an ao2 object or wasn't unlocked successfully
1The object was unlocked and it's reference count was decremented

Definition at line 800 of file astobj2.h.

◆ ao2_weakproxy_subscribe()

int ao2_weakproxy_subscribe ( void *  weakproxy,
ao2_weakproxy_notification_cb  cb,
void *  data,
int  flags 
)

Request notification when weakproxy points to NULL.

Since
14.0.0
Parameters
weakproxyThe weak object
cbProcedure to call when no real object is associated
dataPassed to cb
flagsOBJ_NOLOCK to avoid locking weakproxy.
Return values
0Success
-1Failure
Note
Callbacks are run in the reverse order of subscriptions.
This procedure will allow the same cb / data pair to be added to the same weakproxy multiple times.
It is the caller's responsibility to ensure that *data is valid until after cb() is run or ao2_weakproxy_unsubscribe is called.
If the weakproxy currently points to NULL the callback will be run immediately, without being added to the subscriber list.

Definition at line 934 of file astobj2.c.

935{
936 struct astobj2 *weakproxy_internal = INTERNAL_OBJ_CHECK(weakproxy);
937 int ret = -1;
938 int hasobj;
939
940 if (!weakproxy_internal || weakproxy_internal->priv_data.magic != AO2_WEAK) {
941 return -1;
942 }
943
944 if (!(flags & OBJ_NOLOCK)) {
945 ao2_lock(weakproxy);
946 }
947
948 hasobj = weakproxy_internal->priv_data.weakptr != NULL;
949 if (hasobj) {
950 struct ao2_weakproxy *weak = weakproxy;
951 struct ao2_weakproxy_notification *sub = ast_calloc(1, sizeof(*sub));
952
953 if (sub) {
954 sub->cb = cb;
955 sub->data = data;
957 ret = 0;
958 }
959 }
960
961 if (!(flags & OBJ_NOLOCK)) {
962 ao2_unlock(weakproxy);
963 }
964
965 if (!hasobj) {
966 cb(weakproxy, data);
967 ret = 0;
968 }
969
970 return ret;
971}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
static struct stasis_subscription * sub
Statsd channel stats. Exmaple of how to subscribe to Stasis events.

References ao2_lock, ao2_unlock, AO2_WEAK, ast_calloc, AST_LIST_INSERT_HEAD, ao2_weakproxy_notification::cb, ao2_weakproxy_notification::data, stasis_subscription::data, ao2_weakproxy::destroyed_cb, INTERNAL_OBJ_CHECK, ao2_weakproxy_notification::list, __priv_data::magic, NULL, OBJ_NOLOCK, astobj2::priv_data, sub, and __priv_data::weakptr.

Referenced by __ast_named_lock_get(), __ast_sorcery_open(), AST_TEST_DEFINE(), link_topic_proxy(), state_alloc(), and websocket_new().

◆ ao2_weakproxy_unsubscribe()

int ao2_weakproxy_unsubscribe ( void *  weakproxy,
ao2_weakproxy_notification_cb  cb,
void *  data,
int  flags 
)

Remove notification of real object destruction.

Since
14.0.0
Parameters
weakproxyThe weak object
cbCallback to remove from destroy notification list
dataData pointer to match
flagsOBJ_NOLOCK to avoid locking weakproxy. OBJ_MULTIPLE to remove all copies of the same cb / data pair.
Returns
The number of subscriptions removed.
Return values
0cb / data pair not found, nothing removed.
-1Failure due to invalid parameters.
Note
Unless flags includes OBJ_MULTIPLE, this will only remove a single copy of the cb / data pair. If it was subscribed multiple times it must be unsubscribed as many times. The OBJ_MULTIPLE flag can be used to remove matching subscriptions.
When it's time to run callbacks they are copied to a temporary list so the weakproxy can be unlocked before running. That means it's possible for this function to find nothing before the callback is run in another thread.

Definition at line 973 of file astobj2.c.

974{
975 struct astobj2 *internal_weakproxy = INTERNAL_OBJ_CHECK(weakproxy);
976 struct ao2_weakproxy *weak;
978 int ret = 0;
979
980 if (!internal_weakproxy || internal_weakproxy->priv_data.magic != AO2_WEAK || !destroyed_cb) {
981 return -1;
982 }
983
984 if (!(flags & OBJ_NOLOCK)) {
985 ao2_lock(weakproxy);
986 }
987
988 weak = weakproxy;
990 if (sub->cb == destroyed_cb && sub->data == data) {
992 ast_free(sub);
993 ret++;
994 if (!(flags & OBJ_MULTIPLE)) {
995 break;
996 }
997 }
998 }
1000
1001 if (!(flags & OBJ_NOLOCK)) {
1002 ao2_unlock(weakproxy);
1003 }
1004
1005 return ret;
1006}
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.

References ao2_lock, ao2_unlock, AO2_WEAK, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ao2_weakproxy_notification::data, stasis_subscription::data, ao2_weakproxy::destroyed_cb, INTERNAL_OBJ_CHECK, ao2_weakproxy_notification::list, __priv_data::magic, OBJ_MULTIPLE, OBJ_NOLOCK, astobj2::priv_data, and sub.

Referenced by AST_TEST_DEFINE().