summaryrefslogtreecommitdiff
path: root/main/astobj2.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-03-27 17:13:32 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-03-27 17:13:32 +0000
commit38e892b370c81382dab117ef0a3a1bd2104e9520 (patch)
treef457d13a262cff01ee7f438f2d8b6e47070486ca /main/astobj2.c
parent8611bea1224288c972a7b289ee1d18a5fa2001a4 (diff)
Add global ao2 array container.
Global ao2 objects must always exist after initialization because there is no access control to obtain another reference to the global object. It is expected that module configuration could use these new API calls to replace an active configuration parameter object with an updated configuration parameter object. With these new API calls, the global object could be replaced, removed, or referenced without the risk of someone using a stale global object pointer. Review: https://reviewboard.asterisk.org/r/1824/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@360627 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/astobj2.c')
-rw-r--r--main/astobj2.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/main/astobj2.c b/main/astobj2.c
index 32758cfd0..237d0ca85 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -639,6 +639,79 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in
}
+void __ao2_global_obj_release(struct ao2_global_obj *array, const char *tag, const char *file, int line, const char *func, const char *name)
+{
+ unsigned int idx;
+
+ if (!array) {
+ /* For sanity */
+ return;
+ }
+ if (__ast_rwlock_wrlock(file, line, func, &array->lock, name)) {
+ /* Could not get the write lock. */
+ return;
+ }
+
+ /* Release all contained ao2 objects. */
+ idx = array->num_elements;
+ while (idx--) {
+ if (array->obj[idx]) {
+ __ao2_ref_debug(array->obj[idx], -1, tag, file, line, func);
+ array->obj[idx] = NULL;
+ }
+ }
+
+ __ast_rwlock_unlock(file, line, func, &array->lock, name);
+}
+
+void *__ao2_global_obj_replace(struct ao2_global_obj *array, unsigned int idx, void *obj, const char *tag, const char *file, int line, const char *func, const char *name)
+{
+ void *obj_old;
+
+ if (!array || array->num_elements <= idx) {
+ /* For sanity */
+ return NULL;
+ }
+ if (__ast_rwlock_wrlock(file, line, func, &array->lock, name)) {
+ /* Could not get the write lock. */
+ return NULL;
+ }
+
+ if (obj) {
+ __ao2_ref_debug(obj, +1, tag, file, line, func);
+ }
+ obj_old = array->obj[idx];
+ array->obj[idx] = obj;
+
+ __ast_rwlock_unlock(file, line, func, &array->lock, name);
+
+ return obj_old;
+}
+
+void *__ao2_global_obj_ref(struct ao2_global_obj *array, unsigned int idx, const char *tag, const char *file, int line, const char *func, const char *name)
+{
+ void *obj;
+
+ if (!array || array->num_elements <= idx) {
+ /* For sanity */
+ return NULL;
+ }
+ if (__ast_rwlock_rdlock(file, line, func, &array->lock, name)) {
+ /* Could not get the read lock. */
+ return NULL;
+ }
+
+ obj = array->obj[idx];
+ if (obj) {
+ __ao2_ref_debug(obj, +1, tag, file, line, func);
+ }
+
+ __ast_rwlock_unlock(file, line, func, &array->lock, name);
+
+ return obj;
+}
+
+
/* internal callback to destroy a container. */
static void container_destruct(void *c);