[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