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

📄 threadstorage.h

📁 Asterisk-1.4.4最新内核源代码
💻 H
📖 第 1 页 / 共 2 页
字号:
/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 2006, Digium, Inc. * * Russell Bryant <russell@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. *//*! * \file threadstorage.h * \author Russell Bryant <russell@digium.com> * * \brief Definitions to aid in the use of thread local storage*/#ifndef ASTERISK_THREADSTORAGE_H#define ASTERISK_THREADSTORAGE_H#include <pthread.h>#include "asterisk/utils.h"#include "asterisk/inline_api.h"/*! * \brief data for a thread locally stored variable */struct ast_threadstorage {	/*! Ensure that the key is only initialized by one thread */	pthread_once_t once;	/*! The key used to retrieve this thread's data */	pthread_key_t key;	/*! The function that initializes the key */	void (*key_init)(void);};#if defined(DEBUG_THREADLOCALS)void __ast_threadstorage_object_add(void *key, size_t len, const char *file, const char *function, unsigned int line);void __ast_threadstorage_object_remove(void *key);void __ast_threadstorage_object_replace(void *key_old, void *key_new, size_t len);#endif /* defined(DEBUG_THREADLOCALS) *//*! * \brief Define a thread storage variable * * \arg name The name of the thread storage * \arg name_init This is a name used to create the function that gets called *      to initialize this thread storage. It can be anything since it will not *      be referred to anywhere else * * This macro would be used to declare an instance of thread storage in a file. * * Example usage: * \code * AST_THREADSTORAGE(my_buf, my_buf_init); * \endcode */#define AST_THREADSTORAGE(name, name_init) \	AST_THREADSTORAGE_CUSTOM(name, name_init, ast_free) #if !defined(DEBUG_THREADLOCALS)#define AST_THREADSTORAGE_CUSTOM(name, name_init, cleanup)  \static void name_init(void);                                \static struct ast_threadstorage name = {                    \	.once = PTHREAD_ONCE_INIT,                          \	.key_init = name_init,                              \};                                                          \static void name_init(void)                                 \{                                                           \	pthread_key_create(&(name).key, cleanup);           \}#else /* defined(DEBUG_THREADLOCALS) */#define AST_THREADSTORAGE_CUSTOM(name, name_init, cleanup)  \static void name_init(void);                                \static struct ast_threadstorage name = {                    \	.once = PTHREAD_ONCE_INIT,                          \	.key_init = name_init,                              \};                                                          \static void __cleanup_##name(void *data)		    \{							    \	__ast_threadstorage_object_remove(data);	    \	cleanup(data);					    \}							    \static void name_init(void)                                 \{                                                           \	pthread_key_create(&(name).key, __cleanup_##name);  \}#endif /* defined(DEBUG_THREADLOCALS) *//*! * \brief Retrieve thread storage * * \arg ts This is a pointer to the thread storage structure declared by using *      the AST_THREADSTORAGE macro.  If declared with  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be  *      (&my_buf). * \arg init_size This is the amount of space to be allocated the first time *      this thread requests its data. Thus, this should be the size that the *      code accessing this thread storage is assuming the size to be. * * \return This function will return the thread local storage associated with *         the thread storage management variable passed as the first argument. *         The result will be NULL in the case of a memory allocation error. * * Example usage: * \code * AST_THREADSTORAGE(my_buf, my_buf_init); * #define MY_BUF_SIZE   128 * ... * void my_func(const char *fmt, ...) * { *      void *buf; * *      if (!(buf = ast_threadstorage_get(&my_buf, MY_BUF_SIZE))) *           return; *      ... * } * \endcode */#if !defined(DEBUG_THREADLOCALS)AST_INLINE_API(void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),{	void *buf;	pthread_once(&ts->once, ts->key_init);	if (!(buf = pthread_getspecific(ts->key))) {		if (!(buf = ast_calloc(1, init_size)))			return NULL;		pthread_setspecific(ts->key, buf);	}	return buf;})#else /* defined(DEBUG_THREADLOCALS) */AST_INLINE_API(void *__ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size, const char *file, const char *function, unsigned int line),{	void *buf;	pthread_once(&ts->once, ts->key_init);	if (!(buf = pthread_getspecific(ts->key))) {		if (!(buf = ast_calloc(1, init_size)))			return NULL;		pthread_setspecific(ts->key, buf);		__ast_threadstorage_object_add(buf, init_size, file, function, line);	}	return buf;})#define ast_threadstorage_get(ts, init_size) __ast_threadstorage_get(ts, init_size, __FILE__, __PRETTY_FUNCTION__, __LINE__)#endif /* defined(DEBUG_THREADLOCALS) *//*! * \brief A dynamic length string */struct ast_dynamic_str {	/* The current maximum length of the string */	size_t len;	/* The string buffer */	char str[0];};/*! * \brief Create a dynamic length string * * \arg init_len This is the initial length of the string buffer * * \return This function returns a pointer to the dynamic string length.  The *         result will be NULL in the case of a memory allocation error. * * /note The result of this function is dynamically allocated memory, and must *       be free()'d after it is no longer needed. */AST_INLINE_API(struct ast_dynamic_str * attribute_malloc ast_dynamic_str_create(size_t init_len),{	struct ast_dynamic_str *buf;	if (!(buf = ast_calloc(1, sizeof(*buf) + init_len)))		return NULL;		buf->len = init_len;	return buf;})/*! * \brief Retrieve a thread locally stored dynamic string * * \arg ts This is a pointer to the thread storage structure declared by using *      the AST_THREADSTORAGE macro.  If declared with  *      AST_THREADSTORAGE(my_buf, my_buf_init), then this argument would be  *      (&my_buf). * \arg init_len This is the initial length of the thread's dynamic string. The *      current length may be bigger if previous operations in this thread have *      caused it to increase. * * \return This function will return the thread locally storaged dynamic string *         associated with the thread storage management variable passed as the *         first argument. *         The result will be NULL in the case of a memory allocation error. * * Example usage: * \code * AST_THREADSTORAGE(my_str, my_str_init); * #define MY_STR_INIT_SIZE   128 * ... * void my_func(const char *fmt, ...) * { *      struct ast_dynamic_str *buf; * *      if (!(buf = ast_dynamic_str_thread_get(&my_str, MY_STR_INIT_SIZE))) *           return; *      ... * } * \endcode */#if !defined(DEBUG_THREADLOCALS)AST_INLINE_API(struct ast_dynamic_str *ast_dynamic_str_thread_get(struct ast_threadstorage *ts,	size_t init_len),{	struct ast_dynamic_str *buf;	if (!(buf = ast_threadstorage_get(ts, sizeof(*buf) + init_len)))		return NULL;		if (!buf->len)		buf->len = init_len;	return buf;}

⌨️ 快捷键说明

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