diff options
author | Russell Bryant <russell@russellbryant.com> | 2006-10-19 01:00:57 +0000 |
---|---|---|
committer | Russell Bryant <russell@russellbryant.com> | 2006-10-19 01:00:57 +0000 |
commit | bd53e7ee4c45e7cef357f8aba2e8cb842ac11e92 (patch) | |
tree | 5a78268aec79198822639f0fcdc73bbc41984d18 | |
parent | 71c67605caf713bf0ec03e24c1f51703df54c6b1 (diff) |
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
-rw-r--r-- | channels/chan_sip.c | 2 | ||||
-rw-r--r-- | channels/chan_skinny.c | 4 | ||||
-rw-r--r-- | channels/iax2-parser.c | 2 | ||||
-rw-r--r-- | include/asterisk/threadstorage.h | 54 | ||||
-rw-r--r-- | main/channel.c | 2 | ||||
-rw-r--r-- | main/cli.c | 2 | ||||
-rw-r--r-- | main/frame.c | 2 | ||||
-rw-r--r-- | main/logger.c | 4 | ||||
-rw-r--r-- | main/manager.c | 4 | ||||
-rw-r--r-- | main/utils.c | 2 |
10 files changed, 49 insertions, 29 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index a715e60e5..18b232587 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1143,7 +1143,7 @@ static struct ast_register_list { } regl; /*! \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 */ static struct sip_auth *authl = NULL; /*!< Authentication list for realm authentication */ diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 20b715263..fdd8389ef 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -135,10 +135,10 @@ static struct ast_jb_conf default_jbconf = }; static struct ast_jb_conf global_jbconf; -AST_THREADSTORAGE(device2str_threadbuf, device2str_threadbuf_init); +AST_THREADSTORAGE(device2str_threadbuf); #define DEVICE2STR_BUFSIZE 15 -AST_THREADSTORAGE(control2str_threadbuf, control2str_threadbuf_init); +AST_THREADSTORAGE(control2str_threadbuf); #define CONTROL2STR_BUFSIZE 100 /********************* diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c index 0a524e253..09e04c432 100644 --- a/channels/iax2-parser.c +++ b/channels/iax2-parser.c @@ -53,7 +53,7 @@ static int oframes = 0; static void frame_cache_cleanup(void *data); /*! \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 * iax_frame structures, is defined. */ diff --git a/include/asterisk/threadstorage.h b/include/asterisk/threadstorage.h index 14c6d65b9..6964839cb 100644 --- a/include/asterisk/threadstorage.h +++ b/include/asterisk/threadstorage.h @@ -41,35 +41,51 @@ struct ast_threadstorage { pthread_key_t key; /*! The function that initializes the key */ void (*key_init)(void); + /*! Custom initialization function specific to the object */ + void (*custom_init)(void *); }; /*! * \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 + * \arg name The name of the thread storage object * * 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); + * AST_THREADSTORAGE(my_buf); + * \endcode + */ +#define AST_THREADSTORAGE(name) \ + AST_THREADSTORAGE_CUSTOM(name, NULL, NULL) + +/*! + * \brief Define a thread storage variable, with custom initialization and cleanup + * + * \arg name The name of the thread storage object + * \arg init This is a custom that will be called after each thread specific + * object is allocated, with the allocated block of memory passed + * as the argument. + * \arg cleanup This is a custom function that will be called instead of ast_free + * 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(name, name_init) \ - AST_THREADSTORAGE_CUSTOM(name, name_init, ast_free) - -#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); \ +#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 = ast_calloc(1, init_size))) return NULL; + if (ts->custom_init) + ts->custom_init(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 */ diff --git a/main/channel.c b/main/channel.c index 1a4f55dfd..9a53205ce 100644 --- a/main/channel.c +++ b/main/channel.c @@ -100,7 +100,7 @@ static int uniqueint = 0; unsigned long global_fin = 0, global_fout = 0; -AST_THREADSTORAGE(state2str_threadbuf, state2str_threadbuf_init); +AST_THREADSTORAGE(state2str_threadbuf); #define STATE2STR_BUFSIZE 32 /* XXX 100ms ... this won't work with wideband support */ diff --git a/main/cli.c b/main/cli.c index 51807d969..7f1b67d58 100644 --- a/main/cli.c +++ b/main/cli.c @@ -51,7 +51,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") 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() */ #define AST_CLI_INITLEN 256 diff --git a/main/frame.c b/main/frame.c index dc060e113..f797f55fa 100644 --- a/main/frame.c +++ b/main/frame.c @@ -52,7 +52,7 @@ static AST_LIST_HEAD_STATIC(headerlist, ast_frame); static void frame_cache_cleanup(void *data); /*! \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 diff --git a/main/logger.c b/main/logger.c index a8e5c3700..bd876317a 100644 --- a/main/logger.c +++ b/main/logger.c @@ -137,10 +137,10 @@ static int colors[] = { COLOR_BRGREEN }; -AST_THREADSTORAGE(verbose_buf, verbose_buf_init); +AST_THREADSTORAGE(verbose_buf); #define VERBOSE_BUF_INIT_SIZE 128 -AST_THREADSTORAGE(log_buf, log_buf_init); +AST_THREADSTORAGE(log_buf); #define LOG_BUF_INIT_SIZE 128 static int make_components(char *s, int lineno) diff --git a/main/manager.c b/main/manager.c index 98a2b2ad1..b30506444 100644 --- a/main/manager.c +++ b/main/manager.c @@ -101,10 +101,10 @@ struct eventqent *master_eventq = NULL; * 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 -AST_THREADSTORAGE(astman_append_buf, astman_append_buf_init); +AST_THREADSTORAGE(astman_append_buf); #define ASTMAN_APPEND_BUF_INITSIZE 256 /*! \brief Descriptor for an AMI session, either a regular one diff --git a/main/utils.c b/main/utils.c index ceb049f3a..482bb3eaf 100644 --- a/main/utils.c +++ b/main/utils.c @@ -65,7 +65,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") static char base64[64]; 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__) |