Wed Oct 28 11:46:23 2009

Asterisk developer's documentation

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.


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():

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.


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:

Sample Usage:

    struct ao2_container *c;

    c = ao2_container_alloc(MAX_BUCKETS, my_hash_fn, my_cmp_fn);


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).

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).

A container with a single buckets is effectively a linked list. However there is no ordering among elements.

Generated on Wed Oct 28 11:46:23 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6