summaryrefslogtreecommitdiff
path: root/include/asterisk/threadstorage.h
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2006-10-19 01:00:57 +0000
committerRussell Bryant <russell@russellbryant.com>2006-10-19 01:00:57 +0000
commitbd53e7ee4c45e7cef357f8aba2e8cb842ac11e92 (patch)
tree5a78268aec79198822639f0fcdc73bbc41984d18 /include/asterisk/threadstorage.h
parent71c67605caf713bf0ec03e24c1f51703df54c6b1 (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
Diffstat (limited to 'include/asterisk/threadstorage.h')
-rw-r--r--include/asterisk/threadstorage.h54
1 files changed, 37 insertions, 17 deletions
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
*/