Extend the thread storage API such that a custom initialization function can
authorRussell Bryant <russell@russellbryant.com>
Thu, 19 Oct 2006 01:00:57 +0000 (01:00 +0000)
committerRussell Bryant <russell@russellbryant.com>
Thu, 19 Oct 2006 01:00:57 +0000 (01:00 +0000)
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

channels/chan_sip.c
channels/chan_skinny.c
channels/iax2-parser.c
include/asterisk/threadstorage.h
main/channel.c
main/cli.c
main/frame.c
main/logger.c
main/manager.c
main/utils.c

index a715e60..18b2325 100644 (file)
@@ -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 */
index 20b7152..fdd8389 100644 (file)
@@ -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
 
 /*********************
index 0a524e2..09e04c4 100644 (file)
@@ -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. */
index 14c6d65..6964839 100644 (file)
@@ -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
  */
index 1a4f55d..9a53205 100644 (file)
@@ -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 */
index 51807d9..7f1b67d 100644 (file)
@@ -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
index dc060e1..f797f55 100644 (file)
@@ -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
index a8e5c37..bd87631 100644 (file)
@@ -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)
index 98a2b2a..b305064 100644 (file)
@@ -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
index ceb049f..482bb3e 100644 (file)
@@ -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__)