aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/include/asterisk/astobj2.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/include/asterisk/astobj2.h')
-rw-r--r--trunk/include/asterisk/astobj2.h568
1 files changed, 0 insertions, 568 deletions
diff --git a/trunk/include/asterisk/astobj2.h b/trunk/include/asterisk/astobj2.h
deleted file mode 100644
index b02b6cba8..000000000
--- a/trunk/include/asterisk/astobj2.h
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * astobj2 - replacement containers for asterisk data structures.
- *
- * Copyright (C) 2006 Marta Carbone, Luigi Rizzo - Univ. di Pisa, Italy
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-#ifndef _ASTERISK_ASTOBJ2_H
-#define _ASTERISK_ASTOBJ2_H
-
-/*! \file
- * \ref AstObj2
- *
- * \page AstObj2 Object Model implementing objects and containers.
-
-This module implements an abstraction for objects (with locks and
-reference counts), and containers for these user-defined objects,
-also supporting locking, reference counting and callbacks.
-
-The internal implementation of objects and containers is opaque to the user,
-so we can use different data structures as needs arise.
-
-\section AstObj2_UsageObjects USAGE - OBJECTS
-
-An ao2 object is a block of memory that the user code can access,
-and for which the system keeps track (with a bit of help from the
-programmer) of the number of references around. When an object has
-no more references (refcount == 0), it is destroyed, by first
-invoking whatever 'destructor' function the programmer specifies
-(it can be NULL if none is necessary), and then freeing the memory.
-This way objects can be shared without worrying who is in charge
-of freeing them.
-As an additional feature, ao2 objects are associated to individual
-locks.
-
-Creating an object requires the size of the object and
-and a pointer to the destructor function:
-
- struct foo *o;
-
- o = ao2_alloc(sizeof(struct foo), my_destructor_fn);
-
-The value returned points to the user-visible portion of the objects
-(user-data), but is also used as an identifier for all object-related
-operations such as refcount and lock manipulations.
-
-On return from ao2_alloc():
-
- - the object has a refcount = 1;
- - the memory for the object is allocated dynamically and zeroed;
- - we cannot realloc() the object itself;
- - we cannot call free(o) to dispose of the object. Rather, we
- tell the system that we do not need the reference anymore:
-
- ao2_ref(o, -1)
-
- causing the destructor to be called (and then memory freed) when
- the refcount goes to 0. This is also available as ao2_unref(o),
- and returns NULL as a convenience, so you can do things like
-
- o = ao2_unref(o);
-
- and clean the original pointer to prevent errors.
-
-- ao2_ref(o, +1) can be used to modify the refcount on the
- object in case we want to pass it around.
-
-- ao2_lock(obj), ao2_unlock(obj), ao2_trylock(obj) can be used
- to manipulate the lock associated with the object.
-
-
-\section AstObj2_UsageContainers USAGE - CONTAINERS
-
-An ao2 container is an abstract data structure where we can store
-ao2 objects, search them (hopefully in an efficient way), and iterate
-or apply a callback function to them. A container is just an ao2 object
-itself.
-
-A container must first be allocated, specifying the initial
-parameters. At the moment, this is done as follows:
-
- <b>Sample Usage:</b>
- \code
-
- struct ao2_container *c;
-
- c = ao2_container_alloc(MAX_BUCKETS, my_hash_fn, my_cmp_fn);
- \endcode
-
-where
-
-- MAX_BUCKETS is the number of buckets in the hash table,
-- my_hash_fn() is the (user-supplied) function that returns a
- hash key for the object (further reduced modulo MAX_BUCKETS
- by the container's code);
-- my_cmp_fn() is the default comparison function used when doing
- searches on the container,
-
-A container knows little or nothing about the objects it stores,
-other than the fact that they have been created by ao2_alloc().
-All knowledge of the (user-defined) internals of the objects
-is left to the (user-supplied) functions passed as arguments
-to ao2_container_alloc().
-
-If we want to insert an object in a container, we should
-initialize its fields -- especially, those used by my_hash_fn() --
-to compute the bucket to use.
-Once done, we can link an object to a container with
-
- ao2_link(c, o);
-
-The function returns NULL in case of errors (and the object
-is not inserted in the container). Other values mean success
-(we are not supposed to use the value as a pointer to anything).
-
-\note While an object o is in a container, we expect that
-my_hash_fn(o) will always return the same value. The function
-does not lock the object to be computed, so modifications of
-those fields that affect the computation of the hash should
-be done by extracting the object from the container, and
-reinserting it after the change (this is not terribly expensive).
-
-\note A container with a single buckets is effectively a linked
-list. However there is no ordering among elements.
-
-- \ref AstObj2_Containers
-- \ref astobj2.h All documentation for functions and data structures
-
- */
-
-/*! \brief
- * Typedef for an object destructor. This is called just before freeing
- * the memory for the object. It is passed a pointer to the user-defined
- * data of the object.
- */
-typedef void (*ao2_destructor_fn)(void *);
-
-
-/*! \brief
- * Allocate and initialize an object.
- *
- * \param data_size The sizeof() of the user-defined structure.
- * \param destructor_fn The destructor function (can be NULL)
- * \return A pointer to user-data.
- *
- * Allocates a struct astobj2 with sufficient space for the
- * user-defined structure.
- * \note
- * - storage is zeroed; XXX maybe we want a flag to enable/disable this.
- * - the refcount of the object just created is 1
- * - the returned pointer cannot be free()'d or realloc()'ed;
- * rather, we just call ao2_ref(o, -1);
- */
-void *ao2_alloc(const size_t data_size, ao2_destructor_fn destructor_fn);
-
-/*! \brief
- * Reference/unreference an object and return the old refcount.
- *
- * \param o A pointer to the object
- * \param delta Value to add to the reference counter.
- * \return The value of the reference counter before the operation.
- *
- * Increase/decrease the reference counter according
- * the value of delta.
- *
- * If the refcount goes to zero, the object is destroyed.
- *
- * \note The object must not be locked by the caller of this function, as
- * it is invalid to try to unlock it after releasing the reference.
- *
- * \note if we know the pointer to an object, it is because we
- * have a reference count to it, so the only case when the object
- * can go away is when we release our reference, and it is
- * the last one in existence.
- */
-int ao2_ref(void *o, int delta);
-
-/*! \brief
- * Lock an object.
- *
- * \param a A pointer to the object we want lock.
- * \return 0 on success, other values on error.
- */
-int ao2_lock(void *a);
-
-/*! \brief
- * Unlock an object.
- *
- * \param a A pointer to the object we want unlock.
- * \return 0 on success, other values on error.
- */
-int ao2_unlock(void *a);
-
-/*!
- *
- \page AstObj2_Containers AstObj2 Containers
-
-Containers are data structures meant to store several objects,
-and perform various operations on them.
-Internally, objects are stored in lists, hash tables or other
-data structures depending on the needs.
-
-\note NOTA BENE: at the moment the only container we support is the
- hash table and its degenerate form, the list.
-
-Operations on container include:
-
- - c = \b ao2_container_alloc(size, cmp_fn, hash_fn)
- allocate a container with desired size and default compare
- and hash function
-
- - \b ao2_find(c, arg, flags)
- returns zero or more element matching a given criteria
- (specified as arg). Flags indicate how many results we
- want (only one or all matching entries), and whether we
- should unlink the object from the container.
-
- - \b ao2_callback(c, flags, fn, arg)
- apply fn(obj, arg) to all objects in the container.
- Similar to find. fn() can tell when to stop, and
- do anything with the object including unlinking it.
- Note that the entire operation is run with the container
- locked, so noone else can change its content while we work on it.
- However, we pay this with the fact that doing
- anything blocking in the callback keeps the container
- blocked.
- The mechanism is very flexible because the callback function fn()
- can do basically anything e.g. counting, deleting records, etc.
- possibly using arg to store the results.
-
- - \b iterate on a container
- this is done with the following sequence
-
-\code
-
- struct ao2_container *c = ... // our container
- struct ao2_iterator i;
- void *o;
-
- i = ao2_iterator_init(c, flags);
-
- while ( (o = ao2_iterator_next(&i)) ) {
- ... do something on o ...
- ao2_ref(o, -1);
- }
-\endcode
-
- The difference with the callback is that the control
- on how to iterate is left to us.
-
- - \b ao2_ref(c, -1)
- dropping a reference to a container destroys it, very simple!
-
-Containers are ao2 objects themselves, and this is why their
-implementation is simple too.
-
-Before declaring containers, we need to declare the types of the
-arguments passed to the constructor - in turn, this requires
-to define callback and hash functions and their arguments.
-
-- \ref AstObj2
-- \ref astobj2.h
- */
-
-/*! \brief
- * Type of a generic callback function
- * \param obj pointer to the (user-defined part) of an object.
- * \param arg callback argument from ao2_callback()
- * \param flags flags from ao2_callback()
- *
- * The return values are a combination of enum _cb_results.
- * Callback functions are used to search or manipulate objects in a container,
- */
-typedef int (ao2_callback_fn)(void *obj, void *arg, int flags);
-
-/*! \brief a very common callback is one that matches by address. */
-ao2_callback_fn ao2_match_by_addr;
-
-/*! \brief
- * A callback function will return a combination of CMP_MATCH and CMP_STOP.
- * The latter will terminate the search in a container.
- */
-enum _cb_results {
- CMP_MATCH = 0x1, /*!< the object matches the request */
- CMP_STOP = 0x2, /*!< stop the search now */
-};
-
-/*! \brief
- * Flags passed to ao2_callback() and ao2_hash_fn() to modify its behaviour.
- */
-enum search_flags {
- /*! Unlink the object for which the callback function
- * returned CMP_MATCH . This is the only way to extract
- * objects from a container. */
- OBJ_UNLINK = (1 << 0),
- /*! On match, don't return the object hence do not increase
- * its refcount. */
- OBJ_NODATA = (1 << 1),
- /*! Don't stop at the first match in ao2_callback()
- * \note This is not fully implemented. */
- OBJ_MULTIPLE = (1 << 2),
- /*! obj is an object of the same type as the one being searched for,
- * so use the object's hash function for optimized searching.
- * The search function is unaffected (i.e. use the one passed as
- * argument, or match_by_addr if none specified). */
- OBJ_POINTER = (1 << 3),
-};
-
-/*!
- * Type of a generic function to generate a hash value from an object.
- * flags is ignored at the moment. Eventually, it will include the
- * value of OBJ_POINTER passed to ao2_callback().
- */
-typedef int (ao2_hash_fn)(const void *obj, const int flags);
-
-/*! \name Object Containers
- * Here start declarations of containers.
- */
-/*@{ */
-struct ao2_container;
-
-/*! \brief
- * Allocate and initialize a container
- * with the desired number of buckets.
- *
- * We allocate space for a struct astobj_container, struct container
- * and the buckets[] array.
- *
- * \param n_buckets Number of buckets for hash
- * \param hash_fn Pointer to a function computing a hash value.
- * \param cmp_fn Pointer to a function comparating key-value
- * with a string. (can be NULL)
- * \return A pointer to a struct container.
- *
- * destructor is set implicitly.
- */
-struct ao2_container *ao2_container_alloc(const uint n_buckets,
- ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn);
-
-/*! \brief
- * Returns the number of elements in a container.
- */
-int ao2_container_count(struct ao2_container *c);
-/*@} */
-
-/*! \name Object Management
- * Here we have functions to manage objects.
- *
- * We can use the functions below on any kind of
- * object defined by the user.
- */
-/*@{ */
-
-/*!
- * \brief Add an object to a container.
- *
- * \param c the container to operate on.
- * \param newobj the object to be added.
- *
- * \retval NULL on errors
- * \retval newobj on success.
- *
- * This function inserts an object in a container according its key.
- *
- * \note Remember to set the key before calling this function.
- *
- * \note This function automatically increases the reference count to account
- * for the reference that the container now holds to the object.
- */
-void *ao2_link(struct ao2_container *c, void *newobj);
-
-/*!
- * \brief Remove an object from the container
- *
- * \arg c the container
- * \arg obj the object to unlink
- *
- * \retval NULL, always
- *
- * \note The object requested to be unlinked must be valid. However, if it turns
- * out that it is not in the container, this function is still safe to
- * be called.
- *
- * \note If the object gets unlinked from the container, the container's
- * reference to the object will be automatically released.
- */
-void *ao2_unlink(struct ao2_container *c, void *obj);
-
-/*! \brief Used as return value if the flag OBJ_MULTIPLE is set */
-struct ao2_list {
- struct ao2_list *next;
- void *obj; /* pointer to the user portion of the object */
-};
-/*@} */
-
-/*! \brief
- * ao2_callback() is a generic function that applies cb_fn() to all objects
- * in a container, as described below.
- *
- * \param c A pointer to the container to operate on.
- * \param arg passed to the callback.
- * \param flags A set of flags specifying the operation to perform,
- partially used by the container code, but also passed to
- the callback.
- * \return A pointer to the object found/marked,
- * a pointer to a list of objects matching comparison function,
- * NULL if not found.
- *
- * If the function returns any objects, their refcount is incremented,
- * and the caller is in charge of decrementing them once done.
- * Also, in case of multiple values returned, the list used
- * to store the objects must be freed by the caller.
- *
- * Typically, ao2_callback() is used for two purposes:
- * - to perform some action (including removal from the container) on one
- * or more objects; in this case, cb_fn() can modify the object itself,
- * and to perform deletion should set CMP_MATCH on the matching objects,
- * and have OBJ_UNLINK set in flags.
- * - to look for a specific object in a container; in this case, cb_fn()
- * should not modify the object, but just return a combination of
- * CMP_MATCH and CMP_STOP on the desired object.
- * Other usages are also possible, of course.
-
- * This function searches through a container and performs operations
- * on objects according on flags passed.
- * XXX describe better
- * The comparison is done calling the compare function set implicitly.
- * The p pointer can be a pointer to an object or to a key,
- * we can say this looking at flags value.
- * If p points to an object we will search for the object pointed
- * by this value, otherwise we serch for a key value.
- * If the key is not uniq we only find the first matching valued.
- * If we use the OBJ_MARK flags, we mark all the objects matching
- * the condition.
- *
- * The use of flags argument is the follow:
- *
- * OBJ_UNLINK unlinks the object found
- * OBJ_NODATA on match, do return an object
- * Callbacks use OBJ_NODATA as a default
- * functions such as find() do
- * OBJ_MULTIPLE return multiple matches
- * Default for _find() is no.
- * to a key (not yet supported)
- * OBJ_POINTER the pointer is an object pointer
- *
- * In case we return a list, the callee must take care to destroy
- * that list when no longer used.
- *
- * \note When the returned object is no longer in use, ao2_ref() should
- * be used to free the additional reference possibly created by this function.
- */
-void *ao2_callback(struct ao2_container *c,
- enum search_flags flags,
- ao2_callback_fn *cb_fn, void *arg);
-
-/*! ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg)
- * XXX possibly change order of arguments ?
- */
-void *ao2_find(struct ao2_container *c, void *arg, enum search_flags flags);
-
-/*! \brief
- *
- *
- * When we need to walk through a container, we use
- * 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.
- * 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
- * that is before the one the current object is in. In this case, even if
- * you locked the container around the entire iteration loop, you still would
- * not see this object, because it would still be waiting on the container
- * lock so that it can be added.
- * - It would be extremely rare to see an object twice. The only way this can
- * happen is if an object got unlinked from the container and added again
- * during the same iteration. Furthermore, when the object gets added back,
- * it has to be in the current or later bucket for it to be seen again.
- *
- * An iterator must be first initialized with ao2_iterator_init(),
- * then we can use o = ao2_iterator_next() to move from one
- * element to the next. Remember that the object returned by
- * ao2_iterator_next() has its refcount incremented,
- * and the reference must be explicitly released when done with it.
- *
- * Example:
- *
- * \code
- *
- * struct ao2_container *c = ... // the container we want to iterate on
- * struct ao2_iterator i;
- * struct my_obj *o;
- *
- * i = ao2_iterator_init(c, flags);
- *
- * while ( (o = ao2_iterator_next(&i)) ) {
- * ... do something on o ...
- * ao2_ref(o, -1);
- * }
- *
- * \endcode
- *
- */
-
-/*! \brief
- * The Astobj2 iterator
- *
- * \note You are not supposed to know the internals of an iterator!
- * We would like the iterator to be opaque, unfortunately
- * its size needs to be known if we want to store it around
- * without too much trouble.
- * Anyways...
- * The iterator has a pointer to the container, and a flags
- * field specifying various things e.g. whether the container
- * should be locked or not while navigating on it.
- * The iterator "points" to the current object, which is identified
- * by three values:
- *
- * - 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
- * 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.
- */
-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 */
- uint c_version;
- /*! pointer to the current object */
- void *obj;
- /*! container version when the object was created */
- uint version;
-};
-
-struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags);
-
-void *ao2_iterator_next(struct ao2_iterator *a);
-
-/* extra functions */
-void ao2_bt(void); /* backtrace */
-#endif /* _ASTERISK_ASTOBJ2_H */