Change ao2 global array to ao2 global object holder.
[asterisk/asterisk.git] / include / asterisk / astobj2.h
index c0e17e1..9a3234e 100644 (file)
@@ -565,130 +565,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. */
+/*! Global ao2 object holder structure. */
 struct ao2_global_obj {
-       /*! Access lock to the global ao2 array container. */
+       /*! Access lock to the held ao2 object. */
        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];
+       /*! Global ao2 object. */
+       void *obj;
 };
 
 /*!
- * \brief Define a structure to be used to hold a global array of ao2 objects, statically initialized.
+ * \brief Define a global object holder to be used to hold an ao2 object, 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.
+ * \param name This will be the name of the object holder.
  *
  * \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.
+ * This macro creates a global object holder that can be used to
+ * hold an ao2 object accessible using an API.  The structure is
+ * allocated and initialized to be empty.
  *
  * Example usage:
  * \code
- * static AO2_GLOBAL_OBJ_STATIC(global_cfg, 10);
+ * static AO2_GLOBAL_OBJ_STATIC(global_cfg);
  * \endcode
  *
- * This would define \c struct \c global_cfg, intended to hold
- * an array of ao2 objects accessible using an API.
+ * This defines global_cfg, intended to hold an ao2 object
+ * 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;                                                                                                                         \
+#define AO2_GLOBAL_OBJ_STATIC(name)                                                                            \
+       struct ao2_global_obj 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;                                                            \
-               }                                                                                                                               \
+               ast_rwlock_init(&name.lock);                                                                    \
+               name.obj = 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;                                                    \
-                       }                                                                                                                       \
+               if (name.obj) {                                                                                                 \
+                       ao2_ref(name.obj, -1);                                                                          \
+                       name.obj = NULL;                                                                                        \
                }                                                                                                                               \
-               ast_rwlock_destroy(&name.global.lock);                                                  \
+               ast_rwlock_destroy(&name.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),                                                   \
+#define AO2_GLOBAL_OBJ_STATIC(name)                                                                            \
+       struct ao2_global_obj name = {                                                                          \
+               .lock = AST_RWLOCK_INIT_VALUE,                                                                  \
        }
 #endif
 
 /*!
- * \brief Release all global ao2 objects in the global array.
+ * \brief Release the ao2 object held in the global holder.
  * \since 11.0
  *
- * \param array Global ao2 object array container.
+ * \param holder Global ao2 object holder.
  * \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)
+#define ao2_t_global_obj_release(holder, tag)  \
+       __ao2_global_obj_release(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+#define ao2_global_obj_release(holder) \
+       __ao2_global_obj_release(&holder, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
-void __ao2_global_obj_release(struct ao2_global_obj *array, const char *tag, const char *file, int line, const char *func, const char *name);
+void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name);
 
 /*!
- * \brief Replace a global ao2 object in the global array.
+ * \brief Replace an ao2 object in the global holder.
  * \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 holder Global ao2 object holder.
+ * \param obj Object to put into the holder.  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
+ * count to account for the reference that the global holder now
  * holds to the object.
  *
- * \retval Reference to previous global ao2 object stored at the index.
+ * \retval Reference to previous global ao2 object stored.
  * \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)
+#define ao2_t_global_obj_replace(holder, obj, tag)     \
+       __ao2_global_obj_replace(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+#define ao2_global_obj_replace(holder, idx, obj)       \
+       __ao2_global_obj_replace(&holder, (obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+
+void *__ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *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);
+/*!
+ * \brief Replace an ao2 object in the global holder, throwing away any old object.
+ * \since 11.0
+ *
+ * \param holder Global ao2 object holder.
+ * \param obj Object to put into the holder.  Can be NULL.
+ * \param tag used for debugging
+ *
+ * \note This function automatically increases the reference
+ * count to account for the reference that the global holder now
+ * holds to the object.  It also decreases the reference count
+ * of any object being replaced.
+ *
+ * \retval 0 The global object was previously empty
+ * \retval 1 The global object was not previously empty
+ */
+#define ao2_t_global_obj_replace_unref(holder, obj, tag)       \
+       __ao2_global_obj_replace_unref(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+#define ao2_global_obj_replace_unref(holder, obj)      \
+       __ao2_global_obj_replace_unref(&holder, (obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+int __ao2_global_obj_replace_unref(struct ao2_global_obj *holder, 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.
+ * \brief Get a reference to the object stored in the global holder.
  * \since 11.0
  *
- * \param array Global ao2 object array container.
- * \param idx Index to get an object reference in the array.
+ * \param holder Global ao2 object holder.
  * \param tag used for debugging
  *
- * \retval Reference to current global ao2 object stored at the index.
+ * \retval Reference to current ao2 object stored in the holder.
  * \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)
+#define ao2_t_global_obj_ref(holder, tag)      \
+       __ao2_global_obj_ref(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
+#define ao2_global_obj_ref(holder, idx)        \
+       __ao2_global_obj_ref(&holder, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
-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 *__ao2_global_obj_ref(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name);
 
 
 /*!