Add ability to clone ao2 containers.

Occasionally there is a need to put all objects in one container also into
another container.

Some reasons you might need to do this:

1) You need to reconfigure a container.  You would do this by creating a
new container with the new configuration and ao2_container_dup the old
container into it.  Then replace the old container with the new.  Then
destroy the old container.

2) You need the contents of a container to remain stable while operating
on all of the objects.  You would do this by creating a cloned container
of the original with ao2_container_clone.  The cloned container is a
snapshot of the objects at the time of the cloning.  When done, just
destroy the cloned container.

Review: https://reviewboard.asterisk.org/r/1746/


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@357145 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Richard Mudgett
2012-02-28 00:42:38 +00:00
parent ae07610d73
commit 50c8557f03
3 changed files with 215 additions and 0 deletions

View File

@@ -776,6 +776,58 @@ struct ao2_container *__ao2_container_alloc_debug(unsigned int n_buckets,
*/
int ao2_container_count(struct ao2_container *c);
/*!
* \brief Copy all object references in the src container into the dest container.
* \since 11.0
*
* \param dest Container to copy src object references into.
* \param src Container to copy all object references from.
* \param flags OBJ_NOLOCK if a lock is already held on both containers.
* Otherwise, the src container is locked first.
*
* \pre The dest container must be empty. If the duplication fails, the
* dest container will be returned empty.
*
* \note This can potentially be expensive because a malloc is
* needed for every object in the src container.
*
* \retval 0 on success.
* \retval -1 on error.
*/
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags);
/*!
* \brief Create a clone/copy of the given container.
* \since 11.0
*
* \param orig Container to copy all object references from.
* \param flags OBJ_NOLOCK if a lock is already held on the container.
*
* \note This can potentially be expensive because a malloc is
* needed for every object in the orig container.
*
* \retval Clone container on success.
* \retval NULL on error.
*/
struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags);
struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, char *file, int line, const char *funcname, int ref_debug);
#if defined(REF_DEBUG)
#define ao2_t_container_clone(orig, flags, tag) __ao2_container_clone_debug(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
#define ao2_container_clone(orig, flags) __ao2_container_clone_debug(orig, flags, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
#elif defined(__AST_DEBUG_MALLOC)
#define ao2_t_container_clone(orig, flags, tag) __ao2_container_clone_debug(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
#define ao2_container_clone(orig, flags) __ao2_container_clone_debug(orig, flags, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
#else
#define ao2_t_container_clone(orig, flags, tag) __ao2_container_clone(orig, flags)
#define ao2_container_clone(orig, flags) __ao2_container_clone(orig, flags)
#endif
/*@} */
/*! \name Object Management