diff options
Diffstat (limited to 'include/asterisk/astobj2.h')
-rw-r--r-- | include/asterisk/astobj2.h | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h index 7db77a517..22270c19a 100644 --- a/include/asterisk/astobj2.h +++ b/include/asterisk/astobj2.h @@ -277,6 +277,8 @@ Operations on container include: ... do something on o ... ao2_ref(o, -1); } + + ao2_iterator_destroy(&i); \endcode The difference with the callback is that the control @@ -505,15 +507,15 @@ void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags); /*! \brief * * - * When we need to walk through a container, we use + * When we need to walk through a container, we use an * ao2_iterator to keep track of the current position. * * Because the navigation is typically done without holding the - * lock on the container across the loop, - * objects can be inserted or deleted or moved - * while we work. As a consequence, there is no guarantee that - * the we manage to touch all the elements on the list, or it - * is possible that we touch the same object multiple times. + * lock on the container across the loop, objects can be inserted or deleted + * or moved while we work. As a consequence, there is no guarantee that + * we manage to touch all the elements in the container, and it is possible + * that we touch the same object multiple times. + * * However, within the current hash table container, the following is true: * - It is not possible to miss an object in the container while iterating * unless it gets added after the iteration begins and is added to a bucket @@ -532,6 +534,10 @@ void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags); * ao2_iterator_next() has its refcount incremented, * and the reference must be explicitly released when done with it. * + * In addition, ao2_iterator_init() will hold a reference to the container + * being iterated, which will be freed when ao2_iterator_destroy() is called + * to free up the resources used by the iterator (if any). + * * Example: * * \code @@ -547,12 +553,14 @@ void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags); * ao2_ref(o, -1); * } * + * ao2_iterator_destroy(&i); + * * \endcode * */ /*! \brief - * The Astobj2 iterator + * The astobj2 iterator * * \note You are not supposed to know the internals of an iterator! * We would like the iterator to be opaque, unfortunately @@ -568,21 +576,20 @@ void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags); * - a bucket number; * - the object_id, which is also the container version number * when the object was inserted. This identifies the object - * univoquely, however reaching the desired object requires + * uniquely, however reaching the desired object requires * scanning a list. * - a pointer, and a container version when we saved the pointer. * If the container has not changed its version number, then we * can safely follow the pointer to reach the object in constant time. * * Details are in the implementation of ao2_iterator_next() - * A freshly-initialized iterator has bucket=0, version = 0. + * A freshly-initialized iterator has bucket=0, version=0. */ struct ao2_iterator { /*! the container */ struct ao2_container *c; /*! operation flags */ int flags; -#define F_AO2I_DONTLOCK 1 /*!< don't lock when iterating */ /*! current bucket */ int bucket; /*! container version */ @@ -593,10 +600,49 @@ struct ao2_iterator { unsigned int version; }; +/*! Flags that can be passed to ao2_iterator_init() to modify the behavior + * of the iterator. + */ +enum ao2_iterator_flags { + /*! Prevents ao2_iterator_next() from locking the container + * while retrieving the next object from it. + */ + AO2_ITERATOR_DONTLOCK = (1 << 0), +}; + +/*! + * \brief Create an iterator for a container + * + * \param c the container + * \param flags one or more flags from ao2_iterator_flags + * + * \retval the constructed iterator + * + * \note This function does \b not take a pointer to an iterator; + * rather, it returns an iterator structure that should be + * assigned to (overwriting) an existing iterator structure + * allocated on the stack or on the heap. + * + * This function will take a reference on the container being iterated. + * + */ struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags); void *ao2_iterator_next(struct ao2_iterator *a); +/*! + * \brief Destroy a container iterator + * + * \param i the iterator to destroy + * + * \retval none + * + * This function will release the container reference held by the iterator + * and any other resources it may be holding. + * + */ +void ao2_iterator_destroy(struct ao2_iterator *i); + /* extra functions */ void ao2_bt(void); /* backtrace */ #endif /* _ASTERISK_ASTOBJ2_H */ |