⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 astobj.h

📁 Astercon2 开源软交换 2.2.0
💻 H
📖 第 1 页 / 共 2 页
字号:
/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 1999 - 2005, Digium, Inc. * * Mark Spencer <markster@digium.com> * * 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. *//* * Object Model for Asterisk */#ifndef _ASTERISK_ASTOBJ_H#define _ASTERISK_ASTOBJ_H#include <string.h>#include "asterisk/lock.h"#include "asterisk/compiler.h"/*! \file * \brief A set of macros implementing objects and containers. * Macros are used for maximum performance, to support multiple inheritance, * and to be easily integrated into existing structures without additional * malloc calls, etc. * * These macros expect to operate on two different object types, ASTOBJs and * ASTOBJ_CONTAINERs.  These are not actual types, as any struct can be * converted into an ASTOBJ compatible object or container using the supplied * macros. * * <b>Sample Usage:</b> * \code * struct sample_object { *    ASTOBJ_COMPONENTS(struct sample_object); * }; * * struct sample_container { *    ASTOBJ_CONTAINER_COMPONENTS(struct sample_object); * } super_container; * * void sample_object_destroy(struct sample_object *obj) * { *    free(obj); * } * * int init_stuff() * { *    struct sample_object *obj1; *    struct sample_object *found_obj; * *    obj1 = malloc(sizeof(struct sample_object)); * *    ASTOBJ_CONTAINER_INIT(&super_container); * *    ASTOBJ_INIT(obj1); *    ASTOBJ_WRLOCK(obj1); *    ast_copy_string(obj1->name, "obj1", sizeof(obj1->name)); *    ASTOBJ_UNLOCK(obj1); * *    ASTOBJ_CONTAINER_LINK(&super_container, obj1); * *    found_obj = ASTOBJ_CONTAINER_FIND(&super_container, "obj1"); * *    if(found_obj) { *       printf("Found object: %s", found_obj->name);  *       ASTOBJ_UNREF(found_obj,sample_object_destroy); *    } * *    ASTOBJ_CONTAINER_DESTROYALL(&super_container,sample_object_destroy); *    ASTOBJ_CONTAINER_DESTROY(&super_container); *  *    return 0; * } * \endcode */#if defined(__cplusplus) || defined(c_plusplus)extern "C" {#endif#define ASTOBJ_DEFAULT_NAMELEN 	80#define ASTOBJ_DEFAULT_BUCKETS	256#define ASTOBJ_DEFAULT_HASH		ast_strhash#define ASTOBJ_FLAG_MARKED	(1 << 0)		/* Object has been marked for future operation *//* C++ is simply a syntactic crutch for those who cannot think for themselves   in an object oriented way. *//*! \brief Lock an ASTOBJ for reading. */#define ASTOBJ_RDLOCK(object) ast_mutex_lock(&(object)->_lock)/*! \brief Lock an ASTOBJ for writing. */#define ASTOBJ_WRLOCK(object) ast_mutex_lock(&(object)->_lock)/*! \brief Unlock a locked object. */#define ASTOBJ_UNLOCK(object) ast_mutex_unlock(&(object)->_lock)#ifdef ASTOBJ_CONTAINER_HASHMODEL #define __ASTOBJ_HASH(type,hashes) \	type *next[hashes] #else #define __ASTOBJ_HASH(type,hashes) \	type *next[1] #endif	/*! \brief Add ASTOBJ components to a struct (without locking support). * * \param type The datatype of the object. * \param namelen The length to make the name char array. * \param hashes The number of containers the object can be present in. * * This macro adds components to a struct to make it an ASTOBJ.  This macro * differs from ASTOBJ_COMPONENTS_FULL in that it does not create a mutex for * locking. * * <b>Sample Usage:</b> * \code * struct sample_struct { *    ASTOBJ_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1); * }; * \endcode */#define ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes) \	char name[namelen]; \	unsigned int refcount; \	unsigned int objflags; \	__ASTOBJ_HASH(type,hashes)	/*! \brief Add ASTOBJ components to a struct (without locking support). * * \param type The datatype of the object. * * This macro works like #ASTOBJ_COMPONENTS_NOLOCK_FULL() except it only accepts a * type and uses default values for namelen and hashes. *  * <b>Sample Usage:</b> * \code * struct sample_struct_componets { *    ASTOBJ_COMPONENTS_NOLOCK(struct sample_struct); * }; * \endcode */#define ASTOBJ_COMPONENTS_NOLOCK(type) \	ASTOBJ_COMPONENTS_NOLOCK_FULL(type,ASTOBJ_DEFAULT_NAMELEN,1)/*! \brief Add ASTOBJ components to a struct (with locking support). * * \param type The datatype of the object. * * This macro works like #ASTOBJ_COMPONENTS_NOLOCK() except it includes locking * support. * * <b>Sample Usage:</b> * \code * struct sample_struct { *    ASTOBJ_COMPONENTS(struct sample_struct); * }; * \endcode */#define ASTOBJ_COMPONENTS(type) \	ASTOBJ_COMPONENTS_NOLOCK(type); \	ast_mutex_t _lock; 	/*! \brief Add ASTOBJ components to a struct (with locking support). * * \param type The datatype of the object. * \param namelen The length to make the name char array. * \param hashes The number of containers the object can be present in. * * This macro adds components to a struct to make it an ASTOBJ and includes * support for locking. * * <b>Sample Usage:</b> * \code * struct sample_struct { *    ASTOBJ_COMPONENTS_FULL(struct sample_struct,1,1); * }; * \endcode */#define ASTOBJ_COMPONENTS_FULL(type,namelen,hashes) \	ASTOBJ_COMPONENTS_NOLOCK_FULL(type,namelen,hashes); \	ast_mutex_t _lock; /*! \brief Increment an object reference count. * \param object A pointer to the object to operate on. * \return The object. */#define ASTOBJ_REF(object) \	({ \		ASTOBJ_WRLOCK(object); \		(object)->refcount++; \		ASTOBJ_UNLOCK(object); \		(object); \	})	/*! \brief Decrement the reference count on an object. * * \param object A pointer the object to operate on. * \param destructor The destructor to call if the object is no longer referenced.  It will be passed the pointer as an argument. * * This macro unreferences an object and calls the specfied destructor if the * object is no longer referenced.  The destructor should free the object if it * was dynamically allocated. */#define ASTOBJ_UNREF(object,destructor) \	do { \		int newcount = 0; \		ASTOBJ_WRLOCK(object); \		if (__builtin_expect((object)->refcount > 0, 1)) \			newcount = --((object)->refcount); \		else \			ast_log(LOG_WARNING, "Unreferencing unreferenced (object)!\n"); \		ASTOBJ_UNLOCK(object); \		if (newcount == 0) { \			ast_mutex_destroy(&(object)->_lock); \			destructor((object)); \		} \		(object) = NULL; \	} while(0)/*! \brief Mark an ASTOBJ by adding the #ASTOBJ_FLAG_MARKED flag to its objflags mask.  * \param object A pointer to the object to operate on. * * This macro "marks" an object.  Marked objects can later be unlinked from a container using * #ASTOBJ_CONTAINER_PRUNE_MARKED(). *  */#define ASTOBJ_MARK(object) \	do { \		ASTOBJ_WRLOCK(object); \		(object)->objflags |= ASTOBJ_FLAG_MARKED; \		ASTOBJ_UNLOCK(object); \	} while(0)	/*! \brief Unmark an ASTOBJ by subtracting the #ASTOBJ_FLAG_MARKED flag from its objflags mask. * \param object A pointer to the object to operate on. */#define ASTOBJ_UNMARK(object) \	do { \		ASTOBJ_WRLOCK(object); \		(object)->objflags &= ~ASTOBJ_FLAG_MARKED; \		ASTOBJ_UNLOCK(object); \	} while(0)/*! \brief Initialize an object. * \param object A pointer to the object to operate on. * * \note This should only be used on objects that support locking (objects * created with #ASTOBJ_COMPONENTS() or #ASTOBJ_COMPONENTS_FULL()) */#define ASTOBJ_INIT(object) \	do { \		ast_mutex_init(&(object)->_lock); \		object->name[0] = '\0'; \		object->refcount = 1; \	} while(0)/* Containers for objects -- current implementation is linked lists, but   should be able to be converted to hashes relatively easily *//*! \brief Lock an ASTOBJ_CONTAINER for reading. */#define ASTOBJ_CONTAINER_RDLOCK(container) ast_mutex_lock(&(container)->_lock)/*! \brief Lock an ASTOBJ_CONTAINER for writing.  */#define ASTOBJ_CONTAINER_WRLOCK(container) ast_mutex_lock(&(container)->_lock)/*! \brief Unlock an ASTOBJ_CONTAINER. */#define ASTOBJ_CONTAINER_UNLOCK(container) ast_mutex_unlock(&(container)->_lock)#ifdef ASTOBJ_CONTAINER_HASHMODEL#error "Hash model for object containers not yet implemented!"#else/* Linked lists *//*! \brief Create a container for ASTOBJs (without locking support). * * \param type The type of objects the container will hold. * \param hashes Currently unused. * \param buckets Currently unused. * * This macro is used to create a container for ASTOBJs without locking * support. * * <b>Sample Usage:</b> * \code * struct sample_struct_nolock_container { *    ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(struct sample_struct,1,1); * }; * \endcode */#define ASTOBJ_CONTAINER_COMPONENTS_NOLOCK_FULL(type,hashes,buckets) \	type *head/*! \brief Initialize a container. * * \param container A pointer to the container to initialize. * \param hashes Currently unused. * \param buckets Currently unused. * * This macro initializes a container.  It should only be used on containers * that support locking. *  * <b>Sample Usage:</b> * \code * struct sample_struct_container { *    ASTOBJ_CONTAINER_COMPONENTS_FULL(struct sample_struct,1,1); * } container; * * int func() * { *    ASTOBJ_CONTAINER_INIT_FULL(&container,1,1); * } * \endcode */#define ASTOBJ_CONTAINER_INIT_FULL(container,hashes,buckets) \	do { \		ast_mutex_init(&(container)->_lock); \	} while(0)	/*! \brief Destroy a container. * * \param container A pointer to the container to destroy. * \param hashes Currently unused. * \param buckets Currently unused. * * This macro frees up resources used by a container.  It does not operate on * the objects in the container.  To unlink the objects from the container use * #ASTOBJ_CONTAINER_DESTROYALL(). * * \note This macro should only be used on containers with locking support. */#define ASTOBJ_CONTAINER_DESTROY_FULL(container,hashes,buckets) \	do { \		ast_mutex_destroy(&(container)->_lock); \	} while(0)/*! \brief Iterate through the objects in a container. * * \param container A pointer to the container to traverse. * \param continue A condition to allow the traversal to continue. * \param eval A statement to evaluate in the iteration loop. * * This is macro is a little complicated, but it may help to think of it as a * loop.  Basically it iterates through the specfied containter as long as the * condition is met.  Two variables, iterator and next, are provided for use in * your \p eval statement.  See the sample code for an example. * * <b>Sample Usage:</b> * \code * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, { *    ASTOBJ_RDLOCK(iterator); *    printf("Currently iterating over '%s'\n", iterator->name); *    ASTOBJ_UNLOCK(iterator); * } ); * \endcode * * \code * ASTOBJ_CONTAINER_TRAVERSE(&sample_container,1, sample_func(iterator)); * \endcode */#define ASTOBJ_CONTAINER_TRAVERSE(container,continue,eval) \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -