[asterisk-commits] russell: branch
russell/ast_verbose_threadstorage r38419 - /team/russell/ast_...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Jul 28 11:24:25 MST 2006
Author: russell
Date: Fri Jul 28 13:24:24 2006
New Revision: 38419
URL: http://svn.digium.com/view/asterisk?rev=38419&view=rev
Log:
document the threadstorage API
Modified:
team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h
Modified: team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h
URL: http://svn.digium.com/view/asterisk/team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h?rev=38419&r1=38418&r2=38419&view=diff
==============================================================================
--- team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h (original)
+++ team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h Fri Jul 28 13:24:24 2006
@@ -17,8 +17,10 @@
*/
/*!
- \file threadstorage.h
- \brief Definitions to aid in the use of thread local storage
+ * \file threadstorage.h
+ * \author Russell Bryant <russell at digium.com>
+ *
+ * \brief Definitions to aid in the use of thread local storage
*/
#ifndef ASTERISK_THREADSTORAGE_H
@@ -29,12 +31,33 @@
#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);
};
+/*!
+ * \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) \
static void name_init(void); \
static struct ast_threadstorage name = { \
@@ -46,6 +69,36 @@
pthread_key_create(&(name).key, FREE); \
}
+/*!
+ * \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
+ */
AST_INLINE_API(
void *ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size),
{
@@ -62,11 +115,27 @@
}
)
+/*!
+ * \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),
{
@@ -81,6 +150,37 @@
}
)
+/*!
+ * \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_threadget(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * }
+ * \endcode
+ */
AST_INLINE_API(
struct ast_dynamic_str *ast_dynamic_str_threadget(struct ast_threadstorage *ts,
size_t init_len),
@@ -97,11 +197,61 @@
}
)
+/*!
+ * \brief Error codes from __ast_dynamic_str_threadbuild_va()
+ */
enum {
+ /*! An error has occured and the contents of the dynamic string
+ * are undefined */
AST_DYNSTR_BUILD_FAILED = -1,
+ /*! The buffer size for the dynamic string had to be increased, and
+ * __ast_dynamic_str_threadbuild_va() needs to be called again after
+ * a va_end() and va_start().
+ */
AST_DYNSTR_BUILD_RETRY = -2
};
+/*!
+ * \brief Build a thread locally stored dynamic string from a va_list
+ *
+ * \arg buf This is the address of a pointer to an ast_dynamic_str which should
+ * have been retrieved using ast_dynamic_str_threadget. It will need to
+ * be updated in the case that the buffer has to be reallocated to
+ * accomodate a longer string than what it currently has space for.
+ * \arg max_len This is the maximum length to allow the string buffer to grow
+ * to. If this is set to 0, then there is no maximum length.
+ * \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 fmt This is the format string
+ * \arg ap This is the va_list
+ *
+ * \return The return value of this function is the same as that of the printf
+ * family of functions.
+ *
+ * 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;
+ * va_list ap;
+ *
+ * if (!(buf = ast_dynamic_str_threadget(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * va_start(fmt, ap);
+ * ast_dynamic_str_threadbuild_va(&buf, 0, &my_str, fmt, ap);
+ * va_end(ap);
+ *
+ * printf("This is the string we just built: %s\n", buf->str);
+ * ...
+ * }
+ * \endcode
+ */
#define ast_dynamic_str_threadbuild_va(buf, max_len, ts, fmt, ap) \
({ \
int __res; \
@@ -134,24 +284,18 @@
}
)
-AST_INLINE_API(
-int ast_dynamic_str_threadbuild(struct ast_dynamic_str **buf, size_t max_len,
- struct ast_threadstorage *ts, const char *fmt, ...),
-{
- int res;
- va_list ap;
-
- va_start(ap, fmt);
- while ((res = ast_dynamic_str_threadbuild_va(buf, max_len, ts, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {
- va_end(ap);
- va_start(ap, fmt);
- }
- va_end(ap);
-
- return res;
-}
-)
-
+/*!
+ * \brief Build a dynamic string
+ *
+ * \arg buf This is the address of a pointer to an ast_dynamic_str. It will
+ * need to be updated in the case that the buffer has to be reallocated to
+ * accomodate a longer string than what it currently has space for.
+ * \arg max_len This is the maximum length to allow the string buffer to grow
+ * to. If this is set to 0, then there is no maximum length.
+ *
+ * \return The return value of this function is the same as that of the printf
+ * family of functions.
+ */
AST_INLINE_API(
int ast_dynamic_str_build(struct ast_dynamic_str **buf, size_t max_len,
const char *fmt, ...),
@@ -160,14 +304,65 @@
va_list ap;
va_start(ap, fmt);
- while ((res = ast_dynamic_str_threadbuild_va(buf, max_len, NULL, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {
- va_end(ap);
- va_start(ap, fmt);
- }
+ res = ast_dynamic_str_threadbuild_va(buf, max_len, NULL, fmt, ap);
va_end(ap);
return res;
}
)
+/*!
+ * \brief Build a thread locally stored dynamic string from a va_list
+ *
+ * \arg buf This is the address of a pointer to an ast_dynamic_str which should
+ * have been retrieved using ast_dynamic_str_threadget. It will need to
+ * be updated in the case that the buffer has to be reallocated to
+ * accomodate a longer string than what it currently has space for.
+ * \arg max_len This is the maximum length to allow the string buffer to grow
+ * to. If this is set to 0, then there is no maximum length.
+ * \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 fmt This is the format string
+ *
+ * \return The return value of this function is the same as that of the printf
+ * family of functions.
+ *
+ * Example usage:
+ * \code
+ * AST_THREADSTORAGE(my_str, my_str_init);
+ * #define MY_STR_INIT_SIZE 128
+ * ...
+ * void my_func(int arg1, int arg2)
+ * {
+ * struct ast_dynamic_str *buf;
+ * va_list ap;
+ *
+ * if (!(buf = ast_dynamic_str_threadget(&my_str, MY_STR_INIT_SIZE)))
+ * return;
+ * ...
+ * ast_dynamic_str_threadbuild(&buf, 0, &my_str, "arg1: %d arg2: %d\n",
+ * arg1, arg2);
+ *
+ * printf("This is the string we just built: %s\n", buf->str);
+ * ...
+ * }
+ * \endcode
+ */
+AST_INLINE_API(
+int ast_dynamic_str_threadbuild(struct ast_dynamic_str **buf, size_t max_len,
+ struct ast_threadstorage *ts, const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = ast_dynamic_str_threadbuild_va(buf, max_len, ts, fmt, ap);
+ va_end(ap);
+
+ return res;
+}
+)
+
#endif /* ASTERISK_THREADSTORAGE_H */
More information about the asterisk-commits
mailing list