117    const char *tag, 
const char *file, 
int line, 
const char *func)
 
  125        tag, file, line, func);
 
 
  171#if defined(AO2_DEBUG) 
 
  219    __ao2_ref(obj_new, +1, tag ?: 
"Container node creation", file, line, func);
 
  220    node->common.obj = obj_new;
 
 
  341    state->flags = flags;
 
  347        state->descending = 1;
 
  379    if (
state->descending) {
 
  385        if (bucket_cur < 0) {
 
  387            state->bucket_last = 0;
 
  389            state->bucket_last = bucket_cur;
 
  391        state->bucket_start = bucket_cur;
 
  394        for (; 
state->bucket_last <= bucket_cur; --bucket_cur) {
 
  399                if (!
node->common.obj) {
 
  404                if (
state->sort_fn) {
 
  427        if (bucket_cur < 0) {
 
  431            state->bucket_last = bucket_cur + 1;
 
  433        state->bucket_start = bucket_cur;
 
  436        for (; bucket_cur < 
state->bucket_last; ++bucket_cur) {
 
  441                if (!
node->common.obj) {
 
  446                if (
state->sort_fn) {
 
 
  490    flags = 
state->flags;
 
  501    if (
state->descending) {
 
  502        goto hash_descending_resume;
 
  505        for (; 
state->bucket_last <= bucket_cur; --bucket_cur) {
 
  510                if (!
node->common.obj) {
 
  515                if (
state->sort_fn) {
 
  537                if (
node->common.obj) {
 
  542hash_descending_resume:;
 
  546        goto hash_ascending_resume;
 
  549        for (; bucket_cur < 
state->bucket_last; ++bucket_cur) {
 
  554                if (!
node->common.obj) {
 
  559                if (
state->sort_fn) {
 
  581                if (
node->common.obj) {
 
  586hash_ascending_resume:;
 
 
  617            cur_bucket = 
node->my_bucket;
 
  625                if (
node->common.obj) {
 
  636        while (0 <= --cur_bucket) {
 
  639                if (
node->common.obj) {
 
  648            cur_bucket = 
node->my_bucket;
 
  656                if (
node->common.obj) {
 
  667        while (++cur_bucket < self->n_buckets) {
 
  670                if (
node->common.obj) {
 
 
  683#if defined(AO2_DEBUG) 
  696    int i = 
node->my_bucket;
 
  705#if defined(AO2_DEBUG) 
  745#if defined(AO2_DEBUG) 
  758#define FORMAT  "%6s, %16s, %16s, %16s, %16s, %s\n" 
  759#define FORMAT2 "%6d, %16p, %16p, %16p, %16p, " 
  762    int suppressed_buckets = 0;
 
  765    prnt(where, 
"Number of buckets: %d\n\n", self->
n_buckets);
 
  767    prnt(where, 
FORMAT, 
"Bucket", 
"Node", 
"Prev", 
"Next", 
"Obj", 
"Key");
 
  768    for (bucket = 0; bucket < self->
n_buckets; ++bucket) {
 
  771            suppressed_buckets = 0;
 
  779                if (
node->common.obj && prnt_obj) {
 
  780                    prnt_obj(
node->common.obj, where, prnt);
 
  786        } 
else if (!suppressed_buckets) {
 
  787            suppressed_buckets = 1;
 
  788            prnt(where, 
"...\n");
 
  797#if defined(AO2_DEBUG) 
  811#define FORMAT  "%10.10s %10.10s %10.10s\n" 
  812#define FORMAT2 "%10d %10d %10d\n" 
  815    int suppressed_buckets = 0;
 
  817    prnt(where, 
"Number of buckets: %d\n\n", self->
n_buckets);
 
  819    prnt(where, 
FORMAT, 
"Bucket", 
"Objects", 
"Max");
 
  820    for (bucket = 0; bucket < self->
n_buckets; ++bucket) {
 
  821        if (self->
buckets[bucket].max_elements) {
 
  822            suppressed_buckets = 0;
 
  824                self->
buckets[bucket].max_elements);
 
  825        } 
else if (!suppressed_buckets) {
 
  826            suppressed_buckets = 1;
 
  827            prnt(where, 
"...\n");
 
  836#if defined(AO2_DEBUG) 
  855    int count_total_node;
 
  862    count_total_node = 0;
 
  865    for (bucket = 0; bucket < self->
n_buckets; ++bucket) {
 
  903                    ast_log(
LOG_ERROR, 
"Bucket %d list node's prev pointer points to itself!\n",
 
  922                    ast_log(
LOG_ERROR, 
"Bucket %d list node's next pointer points to itself!\n",
 
  937            if (bucket != 
node->my_bucket) {
 
  939                    bucket, 
node->my_bucket);
 
  944            if (!
node->common.obj) {
 
  953            if (bucket != bucket_exp) {
 
  967                obj_last = 
node->common.obj;
 
  972        if (count_obj != self->
buckets[bucket].elements) {
 
  973            ast_log(
LOG_ERROR, 
"Bucket %d object count of %d does not match stat of %d!\n",
 
  974                bucket, count_obj, self->
buckets[bucket].elements);
 
  979        count_total_obj += count_obj;
 
  985            "Total object count of %d does not match ao2_container_count() of %d!\n",
 
  991    if (count_total_node != self->
common.nodes) {
 
  993            count_total_node, self->
common.nodes);
 
 1010#
if defined(AO2_DEBUG)
 
 1011    .link_stat = hash_ao2_link_node_stat,
 
 1012    .unlink_stat = hash_ao2_unlink_node_stat,
 
 
 1068    unsigned int container_options, 
unsigned int n_buckets, 
ao2_hash_fn *hash_fn,
 
 1070    const char *tag, 
const char *file, 
int line, 
const char *func)
 
 1072    unsigned int num_buckets;
 
 1073    size_t container_size;
 
 1080        tag ?: __PRETTY_FUNCTION__, file, line, func);
 
 
 1087    const char *tag, 
const char *file, 
int line, 
const char *func)
 
 
Prototypes for public functions only of internal interest,.
Asterisk main include file. File version handling, generic pbx functions.
enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int keep_stronger)
void() ao2_prnt_obj_fn(void *v_obj, void *where, ao2_prnt_fn *prnt)
Print object key.
unsigned int ao2_options_get(void *obj)
Retrieve the ao2 options used to create the object.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_NO_REF_DEBUG
int ao2_container_check(struct ao2_container *self, enum search_flags flags)
Perform an integrity check on the specified container.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
@ AO2_ITERATOR_DESCENDING
int() ao2_sort_fn(const void *obj_left, const void *obj_right, int flags)
Type of generic container sort function.
int() ao2_hash_fn(const void *obj, int flags)
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func)
search_flags
Flags passed to ao2_callback_fn(), ao2_hash_fn(), and ao2_sort_fn() to modify behaviour.
@ OBJ_ORDER_MASK
Traverse order option field mask.
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_ORDER_DESCENDING
Traverse in descending order (Last to first container object)
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
@ OBJ_ORDER_PRE
Traverse in pre-order (Node then children, for tree container)
@ OBJ_ORDER_ASCENDING
Traverse in ascending order (First to last container object)
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_ORDER_POST
Traverse in post-order (Children then node, for tree container)
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
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
void() ao2_prnt_fn(void *where, const char *fmt,...)
Print output.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT
Reject duplicate objects in container.
@ AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN
Insert objects at the beginning of the container. (Otherwise it is the opposite; insert at the end....
@ 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.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE
Replace objects with duplicate keys in container.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_MASK
The ao2 container objects with duplicate keys option field mask.
void container_destruct(void *_c)
Common, private definitions for astobj2 containers.
void(* ao2_container_statistics)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt)
Display statistics of the specified container.
void(* ao2_container_destroy_fn)(struct ao2_container *self)
Destroy this container.
int(* ao2_container_integrity)(struct ao2_container *self)
Perform an integrity check on the specified container.
struct ao2_container_node *(* ao2_container_new_node_fn)(struct ao2_container *self, void *obj_new, const char *tag, const char *file, int line, const char *func)
Create a new container node.
void(* ao2_container_display)(struct ao2_container *self, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj)
Display contents of the specified container.
#define __container_unlink_node(node, flags)
#define AO2_TRAVERSAL_STATE_SIZE
struct ao2_container_node *(* ao2_iterator_next_fn)(struct ao2_container *self, struct ao2_container_node *prev, enum ao2_iterator_flags flags)
Find the next non-empty iteration node in the container.
struct ao2_container_node *(* ao2_container_find_first_fn)(struct ao2_container *self, enum search_flags flags, void *arg, void *v_state)
Find the first container node in a traversal.
struct ao2_container_node *(* ao2_container_find_next_fn)(struct ao2_container *self, void *v_state, struct ao2_container_node *prev)
Find the next container node in a traversal.
struct ao2_container *(* ao2_container_alloc_empty_clone_fn)(struct ao2_container *self, const char *tag, const char *file, int line, const char *func)
Create an empty copy of this container.
@ AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED
@ AO2_CONTAINER_INSERT_NODE_REJECTED
@ AO2_CONTAINER_INSERT_NODE_INSERTED
@ AO2_UNLINK_NODE_UNLINK_OBJECT
enum ao2_container_insert(* ao2_container_insert_fn)(struct ao2_container *self, struct ao2_container_node *node)
Insert a node into this container.
static void hash_ao2_destroy(struct ao2_container_hash *self)
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)
static struct hash_bucket_node * hash_ao2_new_node(struct ao2_container_hash *self, void *obj_new, const char *tag, const char *file, int line, const char *func)
static enum ao2_container_insert hash_ao2_insert_node(struct ao2_container_hash *self, struct hash_bucket_node *node)
static int hash_zero(const void *user_obj, const int flags)
always zero hash function
static struct ao2_container * hash_ao2_alloc_empty_clone(struct ao2_container_hash *self, const char *tag, const char *file, int line, const char *func)
static struct hash_bucket_node * hash_ao2_find_first(struct ao2_container_hash *self, enum search_flags flags, void *arg, struct hash_traversal_state *state)
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)
static struct hash_bucket_node * hash_ao2_iterator_next(struct ao2_container_hash *self, struct hash_bucket_node *node, enum ao2_iterator_flags flags)
static struct hash_bucket_node * hash_ao2_find_next(struct ao2_container_hash *self, struct hash_traversal_state *state, struct hash_bucket_node *prev)
static void hash_ao2_node_destructor(void *v_doomed)
static const struct ao2_container_methods v_table_hash
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.
Common, private definitions for astobj2.
#define is_ao2_object(user_data)
#define AO2_DEVMODE_STAT(stat)
#define __is_ao2_object(user_data, file, line, func)
static struct ast_channel * iterator_next(struct ast_channelstorage_instance *driver, struct ast_channel_iterator *i)
A set of macros to manage doubly-linked lists.
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_DLLIST_INSERT_AFTER_CURRENT(elm, field)
Inserts a list node after the current node during a traversal.
#define AST_DLLIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_DLLIST_ENTRY(type)
Declare previous/forward links inside a list entry.
#define AST_DLLIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
#define AST_DLLIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_DLLIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_DLLIST_PREV(elm, field)
Returns the previous entry in the list before the given entry.
#define AST_DLLIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_DLLIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list node before the current node during a traversal.
#define AST_DLLIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_DLLIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_DLLIST_FIRST(head)
Returns the first entry contained in a list.
#define AST_DLLIST_LAST(head)
Returns the last entry contained in a list.
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END
Closes a safe loop traversal block.
#define AST_DLLIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
struct hash_bucket buckets[0]
struct ao2_container common
Items common to all containers.
ao2_container_alloc_empty_clone_fn alloc_empty_clone
Create an empty copy of this container.
ao2_container_new_node_fn new_node
ao2_container_find_first_fn traverse_first
struct ao2_container * my_container
unsigned int destroying
TRUE if the container is being destroyed.
const struct ao2_container_methods * v_table
struct hash_bucket_node::@322 links
struct ao2_container_node common
Items common to all container nodes.
struct hash_bucket::@323 list
char check[1/(AO2_TRAVERSAL_STATE_SIZE/sizeof(struct hash_traversal_state))]