40 const char *tag,
const char *
file,
int line,
const char *func)
95 const char *tag,
const char *
file,
int line,
const char *func)
122#if defined(AO2_DEBUG)
133#if defined(AO2_DEBUG)
135 if (self->
v_table->link_stat) {
141#if defined(AO2_DEBUG)
143 ast_log(
LOG_ERROR,
"Container integrity failed after insert or replace.\n");
176 const char *tag,
const char *
file,
int line,
const char *func)
183 flags &= ~OBJ_SEARCH_MASK;
193static int cb_true(
void *user_data,
void *arg,
int flags)
201static int cb_true_data(
void *user_data,
void *arg,
void *data,
int flags)
232 const char *tag,
const char *
file,
int line,
const char *func)
238 void *traversal_state;
269 NULL,
"OBJ_MULTIPLE return container creation");
270 if (!multi_container) {
273 if (!(multi_iterator =
ast_calloc(1,
sizeof(*multi_iterator)))) {
274 ao2_t_ref(multi_container, -1,
"OBJ_MULTIPLE interator creation failed.");
351 if (multi_container) {
365 __ao2_ref(ret, 1, tag ?:
"Traversal found object",
file, line, func);
399 if (multi_container) {
403 "OBJ_MULTIPLE for multiple objects traversal complete.");
404 return multi_iterator;
419 int line,
const char *func)
428 const char *tag,
const char *
file,
int line,
const char *func)
430 void *arged = (
void *) arg;
441 const char *tag,
const char *
file,
int line,
const char *func)
492 ao2_t_ref(
c, +1,
"Init iterator with container.");
540 ao2_t_ref(iter->
c, -1,
"Unref iterator in ao2_iterator_destroy");
557 const char *tag,
const char *
file,
int line,
const char *func)
604 __ao2_ref(ret, +1, tag ?:
"Next iterator object.",
file, line, func);
642 "container_destruct called");
645 if (
c->v_table &&
c->v_table->destroy) {
646 c->v_table->destroy(
c);
649#if defined(AO2_DEBUG)
685 ao2_t_ref(obj, -1,
"Failed to put this object into the dest container.");
738 ao2_t_ref(obj, -1,
"Failed to put this object into the dest container.");
786 __ao2_ref(clone, -1, tag ?:
"Clone creation failed",
file, line, func);
795 prnt(where,
"Invalid container\n");
804 prnt(where,
"Container name: %s\n",
name);
806#if defined(AO2_DEBUG)
808 self->
v_table->dump(self, where, prnt, prnt_obj);
812 prnt(where,
"Container dump not available.\n");
822 prnt(where,
"Invalid container\n");
831 prnt(where,
"Container name: %s\n",
name);
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);
846 prnt(where,
"Maximum empty nodes: %d\n", self->max_empty_nodes);
848 self->
v_table->stats(self, where, prnt);
865#if defined(AO2_DEBUG)
866 if (!self->
v_table->integrity) {
874 res = self->
v_table->integrity(self);
882#if defined(AO2_DEBUG)
885struct ao2_reg_container {
894struct ao2_reg_partial_key {
901struct ao2_reg_match {
909#if defined(AO2_DEBUG)
910static int ao2_reg_sort_cb(
const void *obj_left,
const void *obj_right,
int flags)
912 const struct ao2_reg_container *reg_left = obj_left;
918 const struct ao2_reg_container *reg_right = obj_right;
920 cmp = strcasecmp(reg_left->name, reg_right->name);
925 const char *
name = obj_right;
927 cmp = strcasecmp(reg_left->name,
name);
932 const struct ao2_reg_partial_key *partial_key = obj_right;
934 cmp = strncasecmp(reg_left->name, partial_key->name, partial_key->len);
947#if defined(AO2_DEBUG)
948static void ao2_reg_destructor(
void *v_doomed)
950 struct ao2_reg_container *doomed = v_doomed;
952 if (doomed->registered) {
953 ao2_t_ref(doomed->registered, -1,
"Releasing registered container.");
961#if defined(AO2_DEBUG)
962 struct ao2_reg_container *reg;
971 ao2_t_ref(self, +1,
"Registering container.");
972 reg->registered = self;
973 reg->prnt_obj = prnt_obj;
974 strcpy(reg->name,
name);
976 if (!
ao2_t_link(reg_containers, reg,
"Save registration object.")) {
980 ao2_t_ref(reg, -1,
"Done registering container.");
987#if defined(AO2_DEBUG)
989 "Unregister container");
993#if defined(AO2_DEBUG)
994static int ao2_complete_reg_cb(
void *obj,
void *arg,
int flags)
996 struct ao2_reg_container *reg = obj;
1006#if defined(AO2_DEBUG)
1007static char *complete_container_names(
struct ast_cli_args *
a)
1009 struct ao2_reg_partial_key partial_key;
1015 partial_key.len = strlen(
a->word);
1016 partial_key.name =
a->word;
1018 ao2_complete_reg_cb, &partial_key);
1024#if defined(AO2_DEBUG)
1034static void cli_output(
void *where,
const char *fmt, ...) __attribute__((format(printf, 2, 3)));
1035static
void cli_output(
void *where, const
char *fmt, ...)
1056#if defined(AO2_DEBUG)
1061 struct ao2_reg_container *reg;
1065 e->
command =
"astobj2 container dump";
1067 "Usage: astobj2 container dump <name>\n"
1068 " Show contents of the container <name>.\n";
1071 return complete_container_names(
a);
1083 ao2_t_ref(reg, -1,
"Done with registered container object.");
1092#if defined(AO2_DEBUG)
1097 struct ao2_reg_container *reg;
1101 e->
command =
"astobj2 container stats";
1103 "Usage: astobj2 container stats <name>\n"
1104 " Show statistics about the specified container <name>.\n";
1107 return complete_container_names(
a);
1118 ao2_t_ref(reg, -1,
"Done with registered container object.");
1127#if defined(AO2_DEBUG)
1132 struct ao2_reg_container *reg;
1136 e->
command =
"astobj2 container check";
1138 "Usage: astobj2 container check <name>\n"
1139 " Perform a container integrity check on <name>.\n";
1142 return complete_container_names(
a);
1154 ao2_t_ref(reg, -1,
"Done with registered container object.");
1163#if defined(AO2_DEBUG)
1165 AST_CLI_DEFINE(handle_cli_astobj2_container_dump,
"Show container contents"),
1166 AST_CLI_DEFINE(handle_cli_astobj2_container_stats,
"Show container statistics"),
1167 AST_CLI_DEFINE(handle_cli_astobj2_container_check,
"Perform a container integrity check"),
1171#if defined(AO2_DEBUG)
1172static void container_cleanup(
void)
1174 ao2_t_ref(reg_containers, -1,
"Releasing container registration container");
1175 reg_containers =
NULL;
1183#if defined(AO2_DEBUG)
1186 "Container registration container.");
1187 if (!reg_containers) {
Prototypes for public functions only of internal interest,.
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_calloc(num, len)
A wrapper for calloc()
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.
#define ao2_t_ref(o, delta, tag)
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_RWLOCK
#define ao2_t_find(container, arg, flags, tag)
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
ao2_lock_req
Which lock to request.
#define ao2_t_link(container, obj, tag)
void * __ao2_weakproxy_get_object(void *weakproxy, int flags, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
@ AO2_ITERATOR_DONTLOCK
Assume that the ao2_container is already locked.
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg)
Allocate and initialize an object.
#define ao2_find(container, arg, flags)
#define ao2_t_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn, tag)
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_weakproxy_get_object(weakproxy, flags)
Get the object associated with weakproxy.
int() ao2_callback_data_fn(void *obj, void *arg, void *data, int flags)
Type of a generic callback function.
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_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
void() ao2_prnt_fn(void *where, const char *fmt,...)
Print output.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE
Replace objects with duplicate keys in 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.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
void ao2_iterator_cleanup(struct ao2_iterator *iter)
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_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)
int __ao2_link(struct ao2_container *self, void *obj_new, int flags, 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.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static int dup_obj_cb(void *obj, void *arg, int flags)
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)
static int cb_true_data(void *user_data, void *arg, void *data, int flags)
similar to cb_true, but is an ao2_callback_data_fn instead
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_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.
static int dup_weakproxy_cb(void *proxy, void *arg, int flags)
Copy obj associated with a weakproxy into the arg container.
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)
int ao2_iterator_count(struct ao2_iterator *iter)
Get a count of the iterated container objects.
void ao2_iterator_restart(struct ao2_iterator *iter)
Restart an iteration.
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)
static int cb_true(void *user_data, void *arg, int flags)
special callback that matches all
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 container_destruct(void *_c)
void * __ao2_iterator_next(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func)
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_unlink(struct ao2_container *c, void *user_data, int flags, const char *tag, const char *file, int line, const char *func)
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_match_by_addr(void *user_data, void *arg, int flags)
another convenience function is a callback that matches on address
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flags, const char *tag, const char *file, int line, const char *func)
Common, private definitions for astobj2 containers.
#define AO2_TRAVERSAL_STATE_SIZE
@ AO2_CONTAINER_INSERT_NODE_OBJ_REPLACED
@ AO2_CONTAINER_INSERT_NODE_REJECTED
@ AO2_CONTAINER_INSERT_NODE_INSERTED
@ AO2_UNLINK_NODE_UNREF_NODE
@ AO2_UNLINK_NODE_UNLINK_OBJECT
@ AO2_UNLINK_NODE_DEC_COUNT
@ AO2_UNLINK_NODE_NOUNREF_OBJECT
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 int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
struct ao2_container * container
@ AST_DYNSTR_BUILD_FAILED
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int ast_str_set_va(struct ast_str **buf, ssize_t max_len, const char *fmt, va_list ap)
Set a dynamic string from a va_list.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
ao2_container_insert_fn insert
ao2_container_alloc_empty_clone_fn alloc_empty_clone
Create an empty copy of this container.
ao2_iterator_next_fn iterator_next
ao2_container_find_cleanup_fn traverse_cleanup
ao2_container_new_node_fn new_node
ao2_container_find_next_fn traverse_next
ao2_container_find_first_fn traverse_first
const struct ao2_container_methods * v_table
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
descriptor for a cli entry.
Support for dynamic strings.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
void DO_CRASH_NORETURN __ast_assert_failed(int condition, const char *condition_str, const char *file, int line, const char *function)