summaryrefslogtreecommitdiff
path: root/include/asterisk/astobj2.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asterisk/astobj2.h')
-rw-r--r--include/asterisk/astobj2.h127
1 files changed, 127 insertions, 0 deletions
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index b6bea649e..4b174b05d 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -564,6 +564,133 @@ int __ao2_trylock(void *a, enum ao2_lock_req lock_how, const char *file, const c
*/
void *ao2_object_get_lockaddr(void *obj);
+
+/*! Global ao2 array container base structure. */
+struct ao2_global_obj {
+ /*! Access lock to the global ao2 array container. */
+ ast_rwlock_t lock;
+ /*! Number of elements in the global ao2 array container. */
+ unsigned int num_elements;
+ /*! Global ao2 array container array. */
+ void *obj[0];
+};
+
+/*!
+ * \brief Define a structure to be used to hold a global array of ao2 objects, statically initialized.
+ * \since 11.0
+ *
+ * \param name This will be the name of the defined structure.
+ * \param num_objects Number of ao2 objects to contain.
+ *
+ * \details
+ * This macro creates a structure definition that can be used to
+ * hold an array of ao2 objects accessible using an API. The
+ * structure is allocated and initialized to be empty.
+ *
+ * Example usage:
+ * \code
+ * static AO2_GLOBAL_OBJ_STATIC(global_cfg, 10);
+ * \endcode
+ *
+ * This would define \c struct \c global_cfg, intended to hold
+ * an array of ao2 objects accessible using an API.
+ */
+#ifndef HAVE_PTHREAD_RWLOCK_INITIALIZER
+#define AO2_GLOBAL_OBJ_STATIC(name, num_objects) \
+ struct name { \
+ struct ao2_global_obj global; \
+ void *objs[num_objects]; \
+ } name; \
+ static void __attribute__((constructor)) __init_##name(void) \
+ { \
+ unsigned int idx = (num_objects); \
+ ast_rwlock_init(&name.global.lock); \
+ name.global.num_elements = idx; \
+ while (idx--) { \
+ name.global.obj[idx] = NULL; \
+ } \
+ } \
+ static void __attribute__((destructor)) __fini_##name(void) \
+ { \
+ unsigned int idx = (num_objects); \
+ while (idx--) { \
+ if (name.global.obj[idx]) { \
+ ao2_ref(name.global.obj[idx], -1); \
+ name.global.obj[idx] = NULL; \
+ } \
+ } \
+ ast_rwlock_destroy(&name.global.lock); \
+ } \
+ struct __dummy_##name
+#else
+#define AO2_GLOBAL_OBJ_STATIC(name, num_objects) \
+ struct name { \
+ struct ao2_global_obj global; \
+ void *objs[num_objects]; \
+ } name = { \
+ .global.lock = AST_RWLOCK_INIT_VALUE, \
+ .global.num_elements = (num_objects), \
+ }
+#endif
+
+/*!
+ * \brief Release all global ao2 objects in the global array.
+ * \since 11.0
+ *
+ * \param array Global ao2 object array container.
+ * \param tag used for debugging
+ *
+ * \return Nothing
+ */
+#define ao2_t_global_obj_release(array, tag) \
+ __ao2_global_obj_release(&array.global, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+#define ao2_global_obj_release(array) \
+ __ao2_global_obj_release(&array.global, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+
+void __ao2_global_obj_release(struct ao2_global_obj *array, const char *tag, const char *file, int line, const char *func, const char *name);
+
+/*!
+ * \brief Replace a global ao2 object in the global array.
+ * \since 11.0
+ *
+ * \param array Global ao2 object array container.
+ * \param idx Index to replace in the array.
+ * \param obj Object to put into the array. Can be NULL.
+ * \param tag used for debugging
+ *
+ * \note This function automatically increases the reference
+ * count to account for the reference that the global array now
+ * holds to the object.
+ *
+ * \retval Reference to previous global ao2 object stored at the index.
+ * \retval NULL if no object available.
+ */
+#define ao2_t_global_obj_replace(array, idx, obj, tag) \
+ __ao2_global_obj_replace(&array.global, (idx), (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+#define ao2_global_obj_replace(array, idx, obj) \
+ __ao2_global_obj_replace(&array.global, (idx), (obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+
+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);
+
+/*!
+ * \brief Get a reference to the object stored in the ao2 global array.
+ * \since 11.0
+ *
+ * \param array Global ao2 object array container.
+ * \param idx Index to get an object reference in the array.
+ * \param tag used for debugging
+ *
+ * \retval Reference to current global ao2 object stored at the index.
+ * \retval NULL if no object available.
+ */
+#define ao2_t_global_obj_ref(array, idx, tag) \
+ __ao2_global_obj_ref(&array.global, (idx), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+#define ao2_global_obj_ref(array, idx) \
+ __ao2_global_obj_ref(&array.global, (idx), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #array)
+
+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);
+
+
/*!
\page AstObj2_Containers AstObj2 Containers