#include "asterisk/compat.h"
Go to the source code of this file.
Data Structures | |
struct | ao2_iterator |
When we need to walk through a container, we use ao2_iterator to keep track of the current position. The Astobj2 iterator. More... | |
struct | ao2_list |
Used as return value if the flag OBJ_MULTIPLE is set. More... | |
Object Containers | |
Here start declarations of containers. | |
ao2_container * | ao2_container_alloc (const unsigned int n_buckets, ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn) |
Allocate and initialize a container with the desired number of buckets. | |
int | ao2_container_count (struct ao2_container *c) |
Returns the number of elements in a container. | |
Object Management | |
Here we have functions to manage objects.
We can use the functions below on any kind of object defined by the user. | |
void * | ao2_link (struct ao2_container *c, void *newobj) |
Add an object to a container. | |
void * | ao2_unlink (struct ao2_container *c, void *obj) |
Remove an object from the container. | |
Defines | |
#define | F_AO2I_DONTLOCK 1 |
Typedefs | |
typedef int( | ao2_callback_fn )(void *obj, void *arg, int flags) |
Type of a generic callback function. | |
typedef void(*) | ao2_destructor_fn (void *) |
Typedef for an object destructor. This is called just before freeing the memory for the object. It is passed a pointer to the user-defined data of the object. | |
typedef int( | ao2_hash_fn )(const void *obj, const int flags) |
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 | search_flags { OBJ_UNLINK = (1 << 0), OBJ_NODATA = (1 << 1), OBJ_MULTIPLE = (1 << 2), OBJ_POINTER = (1 << 3) } |
Flags passed to ao2_callback() and ao2_hash_fn() to modify its behaviour. More... | |
Functions | |
void * | ao2_alloc (const size_t data_size, ao2_destructor_fn destructor_fn) |
Allocate and initialize an object. | |
void | ao2_bt (void) |
void * | ao2_callback (struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg) |
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below. | |
void * | ao2_find (struct ao2_container *c, void *arg, enum search_flags flags) |
ao2_iterator | ao2_iterator_init (struct ao2_container *c, int flags) |
void * | ao2_iterator_next (struct ao2_iterator *a) |
int | ao2_lock (void *a) |
Lock an object. | |
int | ao2_ref (void *o, int delta) |
Reference/unreference an object and return the old refcount. | |
int | ao2_trylock (void *a) |
Try locking-- (don't block if fail). | |
int | ao2_unlock (void *a) |
Unlock an object. | |
Variables | |
ao2_callback_fn | ao2_match_by_addr |
a very common callback is one that matches by address. |
Definition in file astobj2.h.
#define F_AO2I_DONTLOCK 1 |
don't lock when iterating
Definition at line 576 of file astobj2.h.
Referenced by __queues_show(), ao2_iterator_next(), interface_exists_global(), and reload_queues().
typedef int( ao2_callback_fn)(void *obj, void *arg, int flags) |
Type of a generic callback function.
obj | pointer to the (user-defined part) of an object. | |
arg | callback argument from ao2_callback() | |
flags | flags from ao2_callback() |
typedef void(*) ao2_destructor_fn(void *) |
typedef int( ao2_hash_fn)(const void *obj, const int flags) |
Type of a generic function to generate a hash value from an object. flags is ignored at the moment. Eventually, it will include the value of OBJ_POINTER passed to ao2_callback().
enum _cb_results |
enum search_flags |
Flags passed to ao2_callback() and ao2_hash_fn() to modify its behaviour.
OBJ_UNLINK | Unlink the object for which the callback function returned CMP_MATCH . This is the only way to extract objects from a container. |
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()
|
OBJ_POINTER | obj is an object of the same type as the one being searched for, so use the object's hash function for optimized searching. The search function is unaffected (i.e. use the one passed as argument, or match_by_addr if none specified). |
Definition at line 325 of file astobj2.h.
00325 { 00326 /*! Unlink the object for which the callback function 00327 * returned CMP_MATCH . This is the only way to extract 00328 * objects from a container. */ 00329 OBJ_UNLINK = (1 << 0), 00330 /*! On match, don't return the object hence do not increase 00331 * its refcount. */ 00332 OBJ_NODATA = (1 << 1), 00333 /*! Don't stop at the first match in ao2_callback() 00334 * \note This is not fully implemented. */ 00335 OBJ_MULTIPLE = (1 << 2), 00336 /*! obj is an object of the same type as the one being searched for, 00337 * so use the object's hash function for optimized searching. 00338 * The search function is unaffected (i.e. use the one passed as 00339 * argument, or match_by_addr if none specified). */ 00340 OBJ_POINTER = (1 << 3), 00341 };
void* ao2_alloc | ( | const size_t | data_size, | |
ao2_destructor_fn | destructor_fn | |||
) |
Allocate and initialize an object.
data_size | The sizeof() of the user-defined structure. | |
destructor_fn | The destructor function (can be NULL) |
Definition at line 248 of file astobj2.c.
References AO2_MAGIC, ast_atomic_fetchadd_int(), ast_calloc, ast_mutex_init(), and EXTERNAL_OBJ.
Referenced by alloc_queue(), ao2_container_alloc(), ast_tcptls_client_start(), ast_tcptls_server_root(), build_device(), build_peer(), build_profile(), build_route(), build_user(), conf_run(), create_queue_member(), dialgroup_write(), get_filestream(), moh_class_malloc(), new_iax(), set_fn(), and xml_translate().
00249 { 00250 /* allocation */ 00251 struct astobj2 *obj; 00252 00253 if (data_size < sizeof(void *)) 00254 data_size = sizeof(void *); 00255 00256 obj = ast_calloc(1, sizeof(*obj) + data_size); 00257 00258 if (obj == NULL) 00259 return NULL; 00260 00261 ast_mutex_init(&obj->priv_data.lock); 00262 obj->priv_data.magic = AO2_MAGIC; 00263 obj->priv_data.data_size = data_size; 00264 obj->priv_data.ref_counter = 1; 00265 obj->priv_data.destructor_fn = destructor_fn; /* can be NULL */ 00266 00267 #ifdef AO2_DEBUG 00268 ast_atomic_fetchadd_int(&ao2.total_objects, 1); 00269 ast_atomic_fetchadd_int(&ao2.total_mem, data_size); 00270 ast_atomic_fetchadd_int(&ao2.total_refs, 1); 00271 #endif 00272 00273 /* return a pointer to the user data */ 00274 return EXTERNAL_OBJ(obj); 00275 }
void ao2_bt | ( | void | ) |
Definition at line 82 of file astobj2.c.
References ast_verbose(), free, and N1.
00083 { 00084 int c, i; 00085 #define N1 20 00086 void *addresses[N1]; 00087 char **strings; 00088 00089 c = backtrace(addresses, N1); 00090 strings = backtrace_symbols(addresses,c); 00091 ast_verbose("backtrace returned: %d\n", c); 00092 for(i = 0; i < c; i++) { 00093 ast_verbose("%d: %p %s\n", i, addresses[i], strings[i]); 00094 } 00095 free(strings); 00096 }
void* ao2_callback | ( | struct ao2_container * | c, | |
const enum search_flags | flags, | |||
ao2_callback_fn * | cb_fn, | |||
void * | arg | |||
) |
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
Browse the container using different stategies accoding the flags.
Definition at line 447 of file astobj2.c.
References ao2_lock(), ao2_ref(), ao2_unlock(), ast_atomic_fetchadd_int(), AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), bucket_list::astobj, ao2_container::buckets, cb_true(), CMP_MATCH, CMP_STOP, ao2_container::elements, bucket_list::entry, EXTERNAL_OBJ, free, ao2_container::hash_fn, INTERNAL_OBJ(), last, LOG_WARNING, match(), ao2_container::n_buckets, OBJ_MULTIPLE, OBJ_NODATA, OBJ_POINTER, OBJ_UNLINK, and ao2_container::version.
Referenced by ao2_find(), ao2_unlink(), ast_moh_destroy(), container_destruct(), delete_users(), get_mohbydigit(), load_config(), load_module(), load_moh_classes(), and unload_module().
00450 { 00451 int i, last; /* search boundaries */ 00452 void *ret = NULL; 00453 00454 if (INTERNAL_OBJ(c) == NULL) /* safety check on the argument */ 00455 return NULL; 00456 00457 if ((flags & (OBJ_MULTIPLE | OBJ_NODATA)) == OBJ_MULTIPLE) { 00458 ast_log(LOG_WARNING, "multiple data return not implemented yet (flags %x)\n", flags); 00459 return NULL; 00460 } 00461 00462 /* override the match function if necessary */ 00463 if (cb_fn == NULL) /* if NULL, match everything */ 00464 cb_fn = cb_true; 00465 /* 00466 * XXX this can be optimized. 00467 * If we have a hash function and lookup by pointer, 00468 * run the hash function. Otherwise, scan the whole container 00469 * (this only for the time being. We need to optimize this.) 00470 */ 00471 if ((flags & OBJ_POINTER)) /* we know hash can handle this case */ 00472 i = c->hash_fn(arg, flags & OBJ_POINTER) % c->n_buckets; 00473 else /* don't know, let's scan all buckets */ 00474 i = -1; /* XXX this must be fixed later. */ 00475 00476 /* determine the search boundaries: i..last-1 */ 00477 if (i < 0) { 00478 i = 0; 00479 last = c->n_buckets; 00480 } else { 00481 last = i + 1; 00482 } 00483 00484 ao2_lock(c); /* avoid modifications to the content */ 00485 00486 for (; i < last ; i++) { 00487 /* scan the list with prev-cur pointers */ 00488 struct bucket_list *cur; 00489 00490 AST_LIST_TRAVERSE_SAFE_BEGIN(&c->buckets[i], cur, entry) { 00491 int match = cb_fn(EXTERNAL_OBJ(cur->astobj), arg, flags) & (CMP_MATCH | CMP_STOP); 00492 00493 /* we found the object, performing operations according flags */ 00494 if (match == 0) { /* no match, no stop, continue */ 00495 continue; 00496 } else if (match == CMP_STOP) { /* no match but stop, we are done */ 00497 i = last; 00498 break; 00499 } 00500 /* we have a match (CMP_MATCH) here */ 00501 if (!(flags & OBJ_NODATA)) { /* if must return the object, record the value */ 00502 /* it is important to handle this case before the unlink */ 00503 ret = EXTERNAL_OBJ(cur->astobj); 00504 ao2_ref(ret, 1); 00505 } 00506 00507 if (flags & OBJ_UNLINK) { /* must unlink */ 00508 struct bucket_list *x = cur; 00509 00510 /* we are going to modify the container, so update version */ 00511 ast_atomic_fetchadd_int(&c->version, 1); 00512 AST_LIST_REMOVE_CURRENT(entry); 00513 /* update number of elements and version */ 00514 ast_atomic_fetchadd_int(&c->elements, -1); 00515 ao2_ref(EXTERNAL_OBJ(x->astobj), -1); 00516 free(x); /* free the link record */ 00517 } 00518 00519 if ((match & CMP_STOP) || (flags & OBJ_MULTIPLE) == 0) { 00520 /* We found the only match we need */ 00521 i = last; /* force exit from outer loop */ 00522 break; 00523 } 00524 if (!(flags & OBJ_NODATA)) { 00525 #if 0 /* XXX to be completed */ 00526 /* 00527 * This is the multiple-return case. We need to link 00528 * the object in a list. The refcount is already increased. 00529 */ 00530 #endif 00531 } 00532 } 00533 AST_LIST_TRAVERSE_SAFE_END; 00534 } 00535 ao2_unlock(c); 00536 return ret; 00537 }
struct ao2_container* ao2_container_alloc | ( | const unsigned int | n_buckets, | |
ao2_hash_fn * | hash_fn, | |||
ao2_callback_fn * | cmp_fn | |||
) |
Allocate and initialize a container with the desired number of buckets.
We allocate space for a struct astobj_container, struct container and the buckets[] array.
n_buckets | Number of buckets for hash | |
hash_fn | Pointer to a function computing a hash value. | |
cmp_fn | Pointer to a function comparating key-value with a string. (can be NULL) |
Definition at line 335 of file astobj2.c.
References ao2_alloc(), ast_atomic_fetchadd_int(), ao2_container::cmp_fn, container_destruct(), ao2_container::hash_fn, hash_zero(), ao2_container::n_buckets, and ao2_container::version.
Referenced by config_text_file_save(), dialgroup_write(), init_queue(), load_module(), and xml_translate().
00337 { 00338 /* XXX maybe consistency check on arguments ? */ 00339 /* compute the container size */ 00340 size_t container_size = sizeof(struct ao2_container) + n_buckets * sizeof(struct bucket); 00341 00342 struct ao2_container *c = ao2_alloc(container_size, container_destruct); 00343 00344 if (!c) 00345 return NULL; 00346 00347 c->version = 1; /* 0 is a reserved value here */ 00348 c->n_buckets = n_buckets; 00349 c->hash_fn = hash_fn ? hash_fn : hash_zero; 00350 c->cmp_fn = cmp_fn; 00351 00352 #ifdef AO2_DEBUG 00353 ast_atomic_fetchadd_int(&ao2.total_containers, 1); 00354 #endif 00355 00356 return c; 00357 }
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 362 of file astobj2.c.
References ao2_container::elements.
Referenced by __queues_show().
00363 { 00364 return c->elements; 00365 }
void* ao2_find | ( | struct ao2_container * | c, | |
void * | arg, | |||
enum search_flags | flags | |||
) |
the find function just invokes the default callback with some reasonable flags.
Definition at line 542 of file astobj2.c.
References ao2_callback(), and ao2_container::cmp_fn.
Referenced by __find_callno(), authenticate_request(), authenticate_verify(), build_peer(), build_user(), compare_weight(), dialgroup_read(), dialgroup_write(), find_peer(), find_profile(), find_pvt(), find_queue_by_name_rt(), find_user(), get_member_penalty(), get_mohbyname(), handle_cli_iax2_unregister(), iax2_destroy_helper(), load_realtime_queue(), phoneprov_callback(), queue_function_queuememberlist(), queue_function_queuewaitingcount(), queue_function_var(), reload_queue_members(), reload_queues(), remove_from_queue(), rt_handle_member_record(), set_fn(), update_queue(), and xml_translate().
00543 { 00544 return ao2_callback(c, flags, c->cmp_fn, arg); 00545 }
struct ao2_iterator ao2_iterator_init | ( | struct ao2_container * | c, | |
int | flags | |||
) |
initialize an iterator so we start from the first object
Definition at line 550 of file astobj2.c.
References ao2_iterator::c, and ao2_iterator::flags.
Referenced by __iax2_show_peers(), __queues_show(), authenticate_reply(), check_access(), cli_console_active(), cli_list_devices(), compare_weight(), complete_iax2_show_peer(), complete_iax2_unregister(), complete_queue(), complete_queue_remove_member(), delete_profiles(), delete_routes(), destroy_pvts(), dialgroup_read(), dump_queue_members(), free_members(), get_member_status(), handle_cli_iax2_show_users(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_show_routes(), iax2_getpeername(), iax2_getpeertrunk(), interface_exists(), interface_exists_global(), manager_iax2_show_peer_list(), manager_queues_status(), manager_queues_summary(), num_available_members(), poke_all_peers(), prune_peers(), prune_users(), queue_function_qac(), queue_function_qac_dep(), queue_function_queuememberlist(), reload_queues(), set_member_paused(), set_member_penalty(), stop_streams(), try_calling(), unload_module(), update_queue(), update_realtime_members(), and update_status().
00551 { 00552 struct ao2_iterator a = { 00553 .c = c, 00554 .flags = flags 00555 }; 00556 00557 return a; 00558 }
void* ao2_iterator_next | ( | struct ao2_iterator * | a | ) |
Definition at line 563 of file astobj2.c.
References ao2_lock(), AST_LIST_NEXT, AST_LIST_TRAVERSE, ao2_iterator::bucket, ao2_container::buckets, ao2_iterator::c, ao2_iterator::c_version, bucket_list::entry, F_AO2I_DONTLOCK, ao2_iterator::flags, INTERNAL_OBJ(), ao2_container::n_buckets, ao2_iterator::obj, bucket_list::version, ao2_iterator::version, and ao2_container::version.
Referenced by __iax2_show_peers(), __queues_show(), authenticate_reply(), check_access(), cli_console_active(), cli_list_devices(), compare_weight(), complete_iax2_show_peer(), complete_iax2_unregister(), complete_queue(), complete_queue_remove_member(), delete_profiles(), delete_routes(), destroy_pvts(), dialgroup_read(), dump_queue_members(), free_members(), get_member_status(), handle_cli_iax2_show_users(), handle_cli_moh_show_classes(), handle_cli_moh_show_files(), handle_show_routes(), iax2_getpeername(), iax2_getpeertrunk(), interface_exists(), interface_exists_global(), manager_iax2_show_peer_list(), manager_queues_status(), manager_queues_summary(), num_available_members(), poke_all_peers(), prune_peers(), prune_users(), queue_function_qac(), queue_function_qac_dep(), queue_function_queuememberlist(), reload_queues(), set_member_paused(), set_member_penalty(), stop_streams(), try_calling(), unload_module(), update_queue(), update_realtime_members(), and update_status().
00564 { 00565 int lim; 00566 struct bucket_list *p = NULL; 00567 void *ret = NULL; 00568 00569 if (INTERNAL_OBJ(a->c) == NULL) 00570 return NULL; 00571 00572 if (!(a->flags & F_AO2I_DONTLOCK)) 00573 ao2_lock(a->c); 00574 00575 /* optimization. If the container is unchanged and 00576 * we have a pointer, try follow it 00577 */ 00578 if (a->c->version == a->c_version && (p = a->obj) ) { 00579 if ( (p = AST_LIST_NEXT(p, entry)) ) 00580 goto found; 00581 /* nope, start from the next bucket */ 00582 a->bucket++; 00583 a->version = 0; 00584 a->obj = NULL; 00585 } 00586 00587 lim = a->c->n_buckets; 00588 00589 /* Browse the buckets array, moving to the next 00590 * buckets if we don't find the entry in the current one. 00591 * Stop when we find an element with version number greater 00592 * than the current one (we reset the version to 0 when we 00593 * switch buckets). 00594 */ 00595 for (; a->bucket < lim; a->bucket++, a->version = 0) { 00596 /* scan the current bucket */ 00597 AST_LIST_TRAVERSE(&a->c->buckets[a->bucket], p, entry) { 00598 if (p->version > a->version) 00599 goto found; 00600 } 00601 } 00602 00603 found: 00604 if (p) { 00605 a->version = p->version; 00606 a->obj = p; 00607 a->c_version = a->c->version; 00608 ret = EXTERNAL_OBJ(p->astobj); 00609 /* inc refcount of returned object */ 00610 ao2_ref(ret, 1); 00611 } 00612 00613 if (!(a->flags & F_AO2I_DONTLOCK)) 00614 ao2_unlock(a->c); 00615 00616 return ret; 00617 }
void* ao2_link | ( | struct ao2_container * | c, | |
void * | newobj | |||
) |
Add an object to a container.
c | the container to operate on. | |
newobj | the object to be added. |
NULL | on errors | |
newobj | on success. |
This function automatically increases the reference count to account for the reference that the container now holds to the object.
Definition at line 381 of file astobj2.c.
References ao2_lock(), ao2_ref(), ao2_unlock(), ast_atomic_fetchadd_int(), ast_calloc, AST_LIST_INSERT_TAIL, bucket_list::entry, INTERNAL_OBJ(), and OBJ_POINTER.
Referenced by add_to_queue(), build_device(), build_route(), dialgroup_write(), moh_register(), reload_queues(), rt_handle_member_record(), set_config(), set_fn(), store_by_peercallno(), store_by_transfercallno(), and xml_translate().
00382 { 00383 int i; 00384 /* create a new list entry */ 00385 struct bucket_list *p; 00386 struct astobj2 *obj = INTERNAL_OBJ(user_data); 00387 00388 if (!obj) 00389 return NULL; 00390 00391 if (INTERNAL_OBJ(c) == NULL) 00392 return NULL; 00393 00394 p = ast_calloc(1, sizeof(*p)); 00395 if (!p) 00396 return NULL; 00397 00398 i = c->hash_fn(user_data, OBJ_POINTER); 00399 00400 ao2_lock(c); 00401 i %= c->n_buckets; 00402 p->astobj = obj; 00403 p->version = ast_atomic_fetchadd_int(&c->version, 1); 00404 AST_LIST_INSERT_TAIL(&c->buckets[i], p, entry); 00405 ast_atomic_fetchadd_int(&c->elements, 1); 00406 ao2_ref(user_data, +1); 00407 ao2_unlock(c); 00408 00409 return p; 00410 }
int ao2_lock | ( | void * | a | ) |
Lock an object.
a | A pointer to the object we want lock. |
Definition at line 130 of file astobj2.c.
References ast_atomic_fetchadd_int(), ast_mutex_lock(), INTERNAL_OBJ(), __priv_data::lock, and astobj2::priv_data.
Referenced by __queues_show(), add_to_queue(), ao2_callback(), ao2_iterator_next(), ao2_link(), compare_weight(), complete_queue_remove_member(), end_bridge_callback(), find_queue_by_name_rt(), get_member_penalty(), get_member_status(), interface_exists_global(), is_our_turn(), join_queue(), leave_queue(), load_realtime_queue(), manager_queues_status(), manager_queues_summary(), moh_release(), mohalloc(), monmp3thread(), queue_function_qac(), queue_function_qac_dep(), queue_function_queuememberlist(), queue_function_queuewaitingcount(), queue_function_var(), recalc_holdtime(), record_abandoned(), reload_queue_members(), reload_queues(), remove_from_queue(), ring_entry(), set_member_paused(), set_member_penalty(), try_calling(), update_queue(), update_realtime_members(), and update_status().
00134 { 00135 struct astobj2 *p = INTERNAL_OBJ(user_data); 00136 00137 if (p == NULL) 00138 return -1; 00139 00140 #ifdef AO2_DEBUG 00141 ast_atomic_fetchadd_int(&ao2.total_locked, 1); 00142 #endif 00143 00144 #ifndef DEBUG_THREADS 00145 return ast_mutex_lock(&p->priv_data.lock); 00146 #else 00147 return __ast_pthread_mutex_lock(file, line, func, var, &p->priv_data.lock); 00148 #endif 00149 }
int ao2_ref | ( | void * | o, | |
int | delta | |||
) |
Reference/unreference an object and return the old refcount.
o | A pointer to the object | |
delta | Value to add to the reference counter. |
If the refcount goes to zero, the object is destroyed.
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.
Definition at line 200 of file astobj2.c.
References ast_atomic_fetchadd_int(), ast_log(), ast_mutex_destroy(), __priv_data::data_size, __priv_data::destructor_fn, free, INTERNAL_OBJ(), __priv_data::lock, LOG_ERROR, astobj2::priv_data, and __priv_data::ref_counter.
Referenced by __find_callno(), __queues_show(), __unload_module(), add_to_queue(), alloc_queue(), announce_thread(), ao2_callback(), ao2_link(), ast_closestream(), ast_filestream_frame_freed(), ast_make_file_from_fd(), ast_readaudio_callback(), ast_readframe(), ast_readvideo_callback(), ast_tcptls_client_start(), ast_tcptls_server_root(), cd_cb(), compare_weight(), complete_queue_remove_member(), conf_free(), conf_run(), config_text_file_save(), copy_socket_data(), destroy_queue(), dialgroup_read(), dialgroup_write(), dump_queue_members(), end_bridge_callback(), end_bridge_callback_data_fixup(), free_members(), get_member_penalty(), get_member_status(), group_destroy(), hangupcalls(), httpd_helper_thread(), iax2_destroy(), interface_exists(), interface_exists_global(), load_module(), manager_queues_status(), manager_queues_summary(), new_iax(), num_available_members(), parse_moved_contact(), peer_ref(), peer_unref(), queue_function_qac(), queue_function_qac_dep(), queue_function_queuememberlist(), queue_ref(), queue_unref(), ref_pvt(), reload_queues(), remove_from_queue(), rt_handle_member_record(), set_member_paused(), set_member_penalty(), set_socket_transport(), sip_destroy_peer(), sip_prepare_socket(), sip_tcp_locate(), try_calling(), unload_module(), unref_profile(), unref_pvt(), unref_route(), update_queue(), update_realtime_members(), update_status(), user_ref(), user_unref(), and xml_translate().
00201 { 00202 int current_value; 00203 int ret; 00204 struct astobj2 *obj = INTERNAL_OBJ(user_data); 00205 00206 if (obj == NULL) 00207 return -1; 00208 00209 /* if delta is 0, just return the refcount */ 00210 if (delta == 0) 00211 return (obj->priv_data.ref_counter); 00212 00213 /* we modify with an atomic operation the reference counter */ 00214 ret = ast_atomic_fetchadd_int(&obj->priv_data.ref_counter, delta); 00215 current_value = ret + delta; 00216 00217 #ifdef AO2_DEBUG 00218 ast_atomic_fetchadd_int(&ao2.total_refs, delta); 00219 #endif 00220 00221 /* this case must never happen */ 00222 if (current_value < 0) 00223 ast_log(LOG_ERROR, "refcount %d on object %p\n", current_value, user_data); 00224 00225 if (current_value <= 0) { /* last reference, destroy the object */ 00226 if (obj->priv_data.destructor_fn != NULL) 00227 obj->priv_data.destructor_fn(user_data); 00228 00229 ast_mutex_destroy(&obj->priv_data.lock); 00230 #ifdef AO2_DEBUG 00231 ast_atomic_fetchadd_int(&ao2.total_mem, - obj->priv_data.data_size); 00232 ast_atomic_fetchadd_int(&ao2.total_objects, -1); 00233 #endif 00234 /* for safety, zero-out the astobj2 header and also the 00235 * first word of the user-data, which we make sure is always 00236 * allocated. */ 00237 memset(obj, '\0', sizeof(struct astobj2 *) + sizeof(void *) ); 00238 free(obj); 00239 } 00240 00241 return ret; 00242 }
int ao2_trylock | ( | void * | a | ) |
Try locking-- (don't block if fail).
a | A pointer to the object we want to lock. |
Definition at line 174 of file astobj2.c.
References ast_atomic_fetchadd_int(), ast_mutex_trylock(), INTERNAL_OBJ(), __priv_data::lock, and astobj2::priv_data.
00178 { 00179 struct astobj2 *p = INTERNAL_OBJ(user_data); 00180 int ret; 00181 00182 if (p == NULL) 00183 return -1; 00184 #ifndef DEBUG_THREADS 00185 ret = ast_mutex_trylock(&p->priv_data.lock); 00186 #else 00187 ret = __ast_pthread_mutex_trylock(file, line, func, var, &p->priv_data.lock); 00188 #endif 00189 00190 #ifdef AO2_DEBUG 00191 if (!ret) 00192 ast_atomic_fetchadd_int(&ao2.total_locked, 1); 00193 #endif 00194 return ret; 00195 }
void* ao2_unlink | ( | struct ao2_container * | c, | |
void * | obj | |||
) |
Remove an object from the container.
NULL,always |
If the object gets unlinked from the container, the container's reference to the object will be automatically released.
Definition at line 424 of file astobj2.c.
References ao2_callback(), ao2_match_by_addr, INTERNAL_OBJ(), OBJ_NODATA, OBJ_POINTER, and OBJ_UNLINK.
Referenced by build_user(), delete_profiles(), delete_routes(), destroy_pvts(), dialgroup_write(), find_queue_by_name_rt(), free_members(), handle_cli_iax2_prune_realtime(), leave_queue(), prune_users(), reload_queues(), remove_by_peercallno(), remove_by_transfercallno(), remove_from_queue(), unlink_peer(), unload_module(), and update_realtime_members().
00425 { 00426 if (INTERNAL_OBJ(user_data) == NULL) /* safety check on the argument */ 00427 return NULL; 00428 00429 ao2_callback(c, OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA, ao2_match_by_addr, user_data); 00430 00431 return NULL; 00432 }
int ao2_unlock | ( | void * | a | ) |
Unlock an object.
a | A pointer to the object we want unlock. |
Definition at line 152 of file astobj2.c.
References ast_atomic_fetchadd_int(), ast_mutex_unlock(), INTERNAL_OBJ(), __priv_data::lock, and astobj2::priv_data.
Referenced by __queues_show(), add_to_queue(), ao2_callback(), ao2_link(), compare_weight(), complete_queue_remove_member(), end_bridge_callback(), find_queue_by_name_rt(), get_member_penalty(), get_member_status(), interface_exists_global(), is_our_turn(), join_queue(), leave_queue(), load_realtime_queue(), manager_queues_status(), manager_queues_summary(), moh_release(), mohalloc(), monmp3thread(), queue_function_qac(), queue_function_qac_dep(), queue_function_queuememberlist(), queue_function_queuewaitingcount(), queue_function_var(), recalc_holdtime(), record_abandoned(), reload_queue_members(), reload_queues(), remove_from_queue(), ring_entry(), set_member_paused(), set_member_penalty(), try_calling(), update_queue(), update_realtime_members(), and update_status().
00156 { 00157 struct astobj2 *p = INTERNAL_OBJ(user_data); 00158 00159 if (p == NULL) 00160 return -1; 00161 00162 #ifdef AO2_DEBUG 00163 ast_atomic_fetchadd_int(&ao2.total_locked, -1); 00164 #endif 00165 00166 #ifndef DEBUG_THREADS 00167 return ast_mutex_unlock(&p->priv_data.lock); 00168 #else 00169 return __ast_pthread_mutex_unlock(file, line, func, var, &p->priv_data.lock); 00170 #endif 00171 }
ao2_callback_fn ao2_match_by_addr |
a very common callback is one that matches by address.
Definition at line 311 of file astobj2.h.
Referenced by ao2_unlink().