mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-06 04:30:28 +00:00
Extend the thread storage API such that a custom initialization function can
be called for each thread specific object after they are allocated. Note that there was already the ability to define a custom cleanup function. Also, if the custom cleanup function is used, it *MUST* call free on the thread specific object at the end. There is no way to have this magically done that I can think of because the cleanup function registered with the pthread implementation will only call the function back with a pointer to the thread specific object, not the parent ast_threadstorage object. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@45623 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -1143,7 +1143,7 @@ static struct ast_register_list {
|
|||||||
} regl;
|
} regl;
|
||||||
|
|
||||||
/*! \brief A per-thread temporary pvt structure */
|
/*! \brief A per-thread temporary pvt structure */
|
||||||
AST_THREADSTORAGE(ts_temp_pvt, temp_pvt_init);
|
AST_THREADSTORAGE(ts_temp_pvt);
|
||||||
|
|
||||||
/*! \todo Move the sip_auth list to AST_LIST */
|
/*! \todo Move the sip_auth list to AST_LIST */
|
||||||
static struct sip_auth *authl = NULL; /*!< Authentication list for realm authentication */
|
static struct sip_auth *authl = NULL; /*!< Authentication list for realm authentication */
|
||||||
|
@@ -135,10 +135,10 @@ static struct ast_jb_conf default_jbconf =
|
|||||||
};
|
};
|
||||||
static struct ast_jb_conf global_jbconf;
|
static struct ast_jb_conf global_jbconf;
|
||||||
|
|
||||||
AST_THREADSTORAGE(device2str_threadbuf, device2str_threadbuf_init);
|
AST_THREADSTORAGE(device2str_threadbuf);
|
||||||
#define DEVICE2STR_BUFSIZE 15
|
#define DEVICE2STR_BUFSIZE 15
|
||||||
|
|
||||||
AST_THREADSTORAGE(control2str_threadbuf, control2str_threadbuf_init);
|
AST_THREADSTORAGE(control2str_threadbuf);
|
||||||
#define CONTROL2STR_BUFSIZE 100
|
#define CONTROL2STR_BUFSIZE 100
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
|
@@ -53,7 +53,7 @@ static int oframes = 0;
|
|||||||
static void frame_cache_cleanup(void *data);
|
static void frame_cache_cleanup(void *data);
|
||||||
|
|
||||||
/*! \brief A per-thread cache of iax_frame structures */
|
/*! \brief A per-thread cache of iax_frame structures */
|
||||||
AST_THREADSTORAGE_CUSTOM(frame_cache, frame_cache_init, frame_cache_cleanup);
|
AST_THREADSTORAGE_CUSTOM(frame_cache, NULL, frame_cache_cleanup);
|
||||||
|
|
||||||
/*! \brief This is just so iax_frames, a list head struct for holding a list of
|
/*! \brief This is just so iax_frames, a list head struct for holding a list of
|
||||||
* iax_frame structures, is defined. */
|
* iax_frame structures, is defined. */
|
||||||
|
@@ -41,35 +41,51 @@ struct ast_threadstorage {
|
|||||||
pthread_key_t key;
|
pthread_key_t key;
|
||||||
/*! The function that initializes the key */
|
/*! The function that initializes the key */
|
||||||
void (*key_init)(void);
|
void (*key_init)(void);
|
||||||
|
/*! Custom initialization function specific to the object */
|
||||||
|
void (*custom_init)(void *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Define a thread storage variable
|
* \brief Define a thread storage variable
|
||||||
*
|
*
|
||||||
* \arg name The name of the thread storage
|
* \arg name The name of the thread storage object
|
||||||
* \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.
|
* This macro would be used to declare an instance of thread storage in a file.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
* \code
|
* \code
|
||||||
* AST_THREADSTORAGE(my_buf, my_buf_init);
|
* AST_THREADSTORAGE(my_buf);
|
||||||
* \endcode
|
* \endcode
|
||||||
*/
|
*/
|
||||||
#define AST_THREADSTORAGE(name, name_init) \
|
#define AST_THREADSTORAGE(name) \
|
||||||
AST_THREADSTORAGE_CUSTOM(name, name_init, ast_free)
|
AST_THREADSTORAGE_CUSTOM(name, NULL, NULL)
|
||||||
|
|
||||||
#define AST_THREADSTORAGE_CUSTOM(name, name_init, cleanup) \
|
/*!
|
||||||
static void name_init(void); \
|
* \brief Define a thread storage variable, with custom initialization and cleanup
|
||||||
static struct ast_threadstorage name = { \
|
*
|
||||||
.once = PTHREAD_ONCE_INIT, \
|
* \arg name The name of the thread storage object
|
||||||
.key_init = name_init, \
|
* \arg init This is a custom that will be called after each thread specific
|
||||||
}; \
|
* object is allocated, with the allocated block of memory passed
|
||||||
static void name_init(void) \
|
* as the argument.
|
||||||
{ \
|
* \arg cleanup This is a custom function that will be called instead of ast_free
|
||||||
pthread_key_create(&(name).key, cleanup); \
|
* when the thread goes away. Note that if this is used, it *MUST*
|
||||||
|
* call free on the allocated memory.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
* \code
|
||||||
|
* AST_THREADSTORAGE(my_buf, my_init, my_cleanup);
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
#define AST_THREADSTORAGE_CUSTOM(name, c_init, c_cleanup) \
|
||||||
|
static void init_##name(void); \
|
||||||
|
static struct ast_threadstorage name = { \
|
||||||
|
.once = PTHREAD_ONCE_INIT, \
|
||||||
|
.key_init = init_##name, \
|
||||||
|
.custom_init = c_init, \
|
||||||
|
}; \
|
||||||
|
static void init_##name(void) \
|
||||||
|
{ \
|
||||||
|
pthread_key_create(&(name).key, c_cleanup); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -111,6 +127,8 @@ void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
|
|||||||
if (!(buf = pthread_getspecific(ts->key))) {
|
if (!(buf = pthread_getspecific(ts->key))) {
|
||||||
if (!(buf = ast_calloc(1, init_size)))
|
if (!(buf = ast_calloc(1, init_size)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (ts->custom_init)
|
||||||
|
ts->custom_init(buf);
|
||||||
pthread_setspecific(ts->key, buf);
|
pthread_setspecific(ts->key, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +136,8 @@ void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
void __ast_threadstorage_cleanup(void *);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief A dynamic length string
|
* \brief A dynamic length string
|
||||||
*/
|
*/
|
||||||
|
@@ -100,7 +100,7 @@ static int uniqueint = 0;
|
|||||||
|
|
||||||
unsigned long global_fin = 0, global_fout = 0;
|
unsigned long global_fin = 0, global_fout = 0;
|
||||||
|
|
||||||
AST_THREADSTORAGE(state2str_threadbuf, state2str_threadbuf_init);
|
AST_THREADSTORAGE(state2str_threadbuf);
|
||||||
#define STATE2STR_BUFSIZE 32
|
#define STATE2STR_BUFSIZE 32
|
||||||
|
|
||||||
/* XXX 100ms ... this won't work with wideband support */
|
/* XXX 100ms ... this won't work with wideband support */
|
||||||
|
@@ -51,7 +51,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
|
|
||||||
extern unsigned long global_fin, global_fout;
|
extern unsigned long global_fin, global_fout;
|
||||||
|
|
||||||
AST_THREADSTORAGE(ast_cli_buf, ast_cli_buf_init);
|
AST_THREADSTORAGE(ast_cli_buf);
|
||||||
|
|
||||||
/*! \brief Initial buffer size for resulting strings in ast_cli() */
|
/*! \brief Initial buffer size for resulting strings in ast_cli() */
|
||||||
#define AST_CLI_INITLEN 256
|
#define AST_CLI_INITLEN 256
|
||||||
|
@@ -52,7 +52,7 @@ static AST_LIST_HEAD_STATIC(headerlist, ast_frame);
|
|||||||
static void frame_cache_cleanup(void *data);
|
static void frame_cache_cleanup(void *data);
|
||||||
|
|
||||||
/*! \brief A per-thread cache of frame headers */
|
/*! \brief A per-thread cache of frame headers */
|
||||||
AST_THREADSTORAGE_CUSTOM(frame_cache, frame_cache_init, frame_cache_cleanup);
|
AST_THREADSTORAGE_CUSTOM(frame_cache, NULL, frame_cache_cleanup);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Maximum ast_frame cache size
|
* \brief Maximum ast_frame cache size
|
||||||
|
@@ -137,10 +137,10 @@ static int colors[] = {
|
|||||||
COLOR_BRGREEN
|
COLOR_BRGREEN
|
||||||
};
|
};
|
||||||
|
|
||||||
AST_THREADSTORAGE(verbose_buf, verbose_buf_init);
|
AST_THREADSTORAGE(verbose_buf);
|
||||||
#define VERBOSE_BUF_INIT_SIZE 128
|
#define VERBOSE_BUF_INIT_SIZE 128
|
||||||
|
|
||||||
AST_THREADSTORAGE(log_buf, log_buf_init);
|
AST_THREADSTORAGE(log_buf);
|
||||||
#define LOG_BUF_INIT_SIZE 128
|
#define LOG_BUF_INIT_SIZE 128
|
||||||
|
|
||||||
static int make_components(char *s, int lineno)
|
static int make_components(char *s, int lineno)
|
||||||
|
@@ -101,10 +101,10 @@ struct eventqent *master_eventq = NULL;
|
|||||||
* has one event in it (Placeholder) in init_manager().
|
* has one event in it (Placeholder) in init_manager().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AST_THREADSTORAGE(manager_event_buf, manager_event_buf_init);
|
AST_THREADSTORAGE(manager_event_buf);
|
||||||
#define MANAGER_EVENT_BUF_INITSIZE 256
|
#define MANAGER_EVENT_BUF_INITSIZE 256
|
||||||
|
|
||||||
AST_THREADSTORAGE(astman_append_buf, astman_append_buf_init);
|
AST_THREADSTORAGE(astman_append_buf);
|
||||||
#define ASTMAN_APPEND_BUF_INITSIZE 256
|
#define ASTMAN_APPEND_BUF_INITSIZE 256
|
||||||
|
|
||||||
/*! \brief Descriptor for an AMI session, either a regular one
|
/*! \brief Descriptor for an AMI session, either a regular one
|
||||||
|
@@ -65,7 +65,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
static char base64[64];
|
static char base64[64];
|
||||||
static char b2a[256];
|
static char b2a[256];
|
||||||
|
|
||||||
AST_THREADSTORAGE(inet_ntoa_buf, inet_ntoa_buf_init);
|
AST_THREADSTORAGE(inet_ntoa_buf);
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
|
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined(__APPLE__) || defined(__CYGWIN__)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user