[asterisk-commits] russell: branch
russell/ast_verbose_threadstorage r38408 - in /team/russell/a...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Jul 28 00:56:29 MST 2006
Author: russell
Date: Fri Jul 28 02:56:28 2006
New Revision: 38408
URL: http://svn.digium.com/view/asterisk?rev=38408&view=rev
Log:
commit my first revision of centralizing the code for thread locally stored
dynamic length string buffers. And yes, it works!
Modified:
team/russell/ast_verbose_threadstorage/cli.c
team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h
Modified: team/russell/ast_verbose_threadstorage/cli.c
URL: http://svn.digium.com/view/asterisk/team/russell/ast_verbose_threadstorage/cli.c?rev=38408&r1=38407&r2=38408&view=diff
==============================================================================
--- team/russell/ast_verbose_threadstorage/cli.c (original)
+++ team/russell/ast_verbose_threadstorage/cli.c Fri Jul 28 02:56:28 2006
@@ -48,49 +48,28 @@
#include "asterisk/app.h"
#include "asterisk/lock.h"
#include "editline/readline/readline.h"
+#include "asterisk/threadstorage.h"
extern unsigned long global_fin, global_fout;
-static pthread_key_t ast_cli_buf_key;
-static pthread_once_t ast_cli_buf_once = PTHREAD_ONCE_INIT;
+AST_THREADSTORAGE(ast_cli_buf, ast_cli_buf_init);
/*! \brief Initial buffer size for resulting strings in ast_cli() */
#define AST_CLI_MAXSTRLEN 256
-static void ast_cli_buf_key_create(void)
-{
- pthread_key_create(&ast_cli_buf_key, FREE);
-}
-
void ast_cli(int fd, char *fmt, ...)
{
- struct {
- size_t len;
- char str[0];
- } *buf;
int res;
+ struct ast_dynamic_str *buf;
va_list ap;
- pthread_once(&ast_cli_buf_once, ast_cli_buf_key_create);
- if (!(buf = pthread_getspecific(ast_cli_buf_key))) {
- if (!(buf = ast_malloc(AST_CLI_MAXSTRLEN + sizeof(*buf))))
- return;
- buf->len = AST_CLI_MAXSTRLEN;
- pthread_setspecific(ast_cli_buf_key, buf);
- }
+ if (!(buf = ast_dynamic_str_threadget(&ast_cli_buf, AST_CLI_MAXSTRLEN)))
+ return;
va_start(ap, fmt);
- res = vsnprintf(buf->str, buf->len, fmt, ap);
- while (res >= buf->len) {
- if (!(buf = ast_realloc(buf, (buf->len * 2) + sizeof(*buf)))) {
- va_end(ap);
- return;
- }
- buf->len *= 2;
- pthread_setspecific(ast_cli_buf_key, buf);
+ while ((res = ast_dynamic_str_threadbuild_va(&buf, 0, &ast_cli_buf, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {
va_end(ap);
va_start(ap, fmt);
- res = vsnprintf(buf->str, buf->len, fmt, ap);
}
va_end(ap);
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=38408&r1=38407&r2=38408&view=diff
==============================================================================
--- team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h (original)
+++ team/russell/ast_verbose_threadstorage/include/asterisk/threadstorage.h Fri Jul 28 02:56:28 2006
@@ -62,4 +62,103 @@
}
)
+struct ast_dynamic_str {
+ size_t len;
+ char str[0];
+};
+
+AST_INLINE_API(
+struct ast_dynamic_str * __attribute__ ((malloc)) ast_dynamic_str_create(size_t init_len),
+{
+ struct ast_dynamic_str *buf;
+
+ if (!(buf = ast_calloc(1, sizeof(*buf) + init_len)))
+ return NULL;
+
+ buf->len = init_len;
+
+ return buf;
+}
+)
+
+AST_INLINE_API(
+struct ast_dynamic_str *ast_dynamic_str_threadget(struct ast_threadstorage *threadstorage,
+ size_t init_len),
+{
+ struct ast_dynamic_str *buf;
+
+ pthread_once(&threadstorage->once, threadstorage->key_init);
+ if (!(buf = pthread_getspecific(threadstorage->key))) {
+ if (!(buf = ast_dynamic_str_create(init_len)))
+ return NULL;
+ pthread_setspecific(threadstorage->key, buf);
+ }
+
+ return buf;
+}
+)
+
+/* A dirty hack. */
+enum {
+ AST_DYNSTR_BUILD_FAILED = -1,
+ AST_DYNSTR_BUILD_RETRY = -2
+};
+
+AST_INLINE_API(
+int ast_dynamic_str_threadbuild_va(struct ast_dynamic_str **buf, size_t max_len,
+ struct ast_threadstorage *threadstorage, const char *fmt, va_list ap),
+{
+ int res;
+
+ res = vsnprintf((*buf)->str, (*buf)->len, fmt, ap);
+
+ if (res >= (*buf)->len && (max_len ? ((*buf)->len <= (max_len / 2)) : 1)) {
+ if (!(*buf = ast_realloc(*buf, ((*buf)->len * 2) + sizeof(*(*buf)))))
+ return AST_DYNSTR_BUILD_FAILED;
+ (*buf)->len *= 2;
+ if (threadstorage)
+ pthread_setspecific(threadstorage->key, *buf);
+ return AST_DYNSTR_BUILD_RETRY;
+ }
+
+ return res;
+}
+)
+
+AST_INLINE_API(
+int ast_dynamic_str_threadbuild(struct ast_dynamic_str **buf, size_t max_len,
+ struct ast_threadstorage *threadstorage, const char *fmt, ...),
+{
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ while ((res = ast_dynamic_str_threadbuild_va(buf, max_len, threadstorage, fmt, ap)) == AST_DYNSTR_BUILD_RETRY) {
+ va_end(ap);
+ va_start(ap, fmt);
+ }
+ va_end(ap);
+
+ return res;
+}
+)
+
+AST_INLINE_API(
+int ast_dynamic_str_build(struct ast_dynamic_str **buf, size_t max_len,
+ const char *fmt, ...),
+{
+ int res;
+ 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);
+ }
+ va_end(ap);
+
+ return res;
+}
+)
+
#endif /* ASTERISK_THREADSTORAGE_H */
More information about the asterisk-commits
mailing list