[asterisk-commits] kpfleming: trunk r176255 - in /trunk: ./ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Feb 16 15:45:55 CST 2009


Author: kpfleming
Date: Mon Feb 16 15:45:54 2009
New Revision: 176255

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=176255
Log:
Merged revisions 176216 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
  r176216 | kpfleming | 2009-02-16 15:10:38 -0600 (Mon, 16 Feb 2009) | 3 lines
  
  fix a flaw in the ast_string_field_build() family of API calls; these functions made no attempt to reuse the space already allocated to a field, so every time the field was written it would allocate new space, leading to what appeared to be a memory leak.
........
  r176254 | kpfleming | 2009-02-16 15:41:46 -0600 (Mon, 16 Feb 2009) | 3 lines

  correct a logic error in the last stringfields commit... don't mark additional space as allocated if the string was built using already-allocated space
........

Modified:
    trunk/   (props changed)
    trunk/include/asterisk/stringfields.h
    trunk/main/utils.c

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/include/asterisk/stringfields.h
URL: http://svn.digium.com/svn-view/asterisk/trunk/include/asterisk/stringfields.h?view=diff&rev=176255&r1=176254&r2=176255
==============================================================================
--- trunk/include/asterisk/stringfields.h (original)
+++ trunk/include/asterisk/stringfields.h Mon Feb 16 15:45:54 2009
@@ -183,7 +183,7 @@
 */
 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
 				  struct ast_string_field_pool **pool_head,
-				  const ast_string_field *ptr, const char *format, ...) __attribute__((format(printf, 4, 5)));
+				  ast_string_field *ptr, const char *format, ...) __attribute__((format(printf, 4, 5)));
 
 /*!
   \internal
@@ -198,7 +198,7 @@
 */
 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
 				     struct ast_string_field_pool **pool_head,
-				     const ast_string_field *ptr, const char *format, va_list a1, va_list a2) __attribute__((format(printf, 4, 0)));
+				     ast_string_field *ptr, const char *format, va_list a1, va_list a2) __attribute__((format(printf, 4, 0)));
 
 /*!
   \brief Declare a string field
@@ -287,7 +287,7 @@
   \return nothing
 */
 #define ast_string_field_ptr_build(x, ptr, fmt, args...) \
-	__ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, ptr, fmt, args)
+	__ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args)
 
 /*!
   \brief Set a field to a complex (built) value
@@ -298,7 +298,7 @@
   \return nothing
 */
 #define ast_string_field_build(x, field, fmt, args...) \
-	__ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, &(x)->field, fmt, args)
+	__ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args)
 
 /*!
   \brief Set a field to a complex (built) value with prebuilt va_lists.
@@ -310,7 +310,7 @@
   \return nothing
 */
 #define ast_string_field_ptr_build_va(x, ptr, fmt, args1, args2) \
-	__ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, ptr, fmt, args1, args2)
+	__ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args1, args2)
 
 /*!
   \brief Set a field to a complex (built) value
@@ -322,6 +322,6 @@
   \return nothing
 */
 #define ast_string_field_build_va(x, field, fmt, args1, args2) \
-	__ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, &(x)->field, fmt, args1, args2)
+	__ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args1, args2)
 
 #endif /* _ASTERISK_STRINGFIELDS_H */

Modified: trunk/main/utils.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/main/utils.c?view=diff&rev=176255&r1=176254&r2=176255
==============================================================================
--- trunk/main/utils.c (original)
+++ trunk/main/utils.c Mon Feb 16 15:45:54 2009
@@ -1587,38 +1587,58 @@
 
 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
 				     struct ast_string_field_pool **pool_head,
-				     const ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
+				     ast_string_field *ptr, const char *format, va_list ap1, va_list ap2)
 {
 	size_t needed;
-	char *dst = (*pool_head)->base + mgr->used;
-	const char **p = (const char **) ptr;
+	size_t available;
 	size_t space = mgr->size - mgr->used;
-
-	/* try to write using available space */
-	needed = vsnprintf(dst, space, format, ap1) + 1;
+	char *target;
+
+	/* if the field already has space allocated, try to reuse it;
+	   otherwise, use the empty space at the end of the current
+	   pool
+	*/
+	if ((*ptr)[0] != '0') {
+		target = (char *) *ptr;
+		available = strlen(target);
+	} else {
+		target = (*pool_head)->base + mgr->used;
+		available = space;
+	}
+
+	needed = vsnprintf(target, available, format, ap1) + 1;
 
 	va_end(ap1);
 
-	if (needed > space) {	/* if it fails, reallocate */
-		size_t new_size = mgr->size * 2;
-
-		while (new_size < needed)
-			new_size *= 2;
-
-		if (add_string_pool(mgr, pool_head, new_size))
-			return;
-
-		dst = (*pool_head)->base + mgr->used;
-		vsprintf(dst, format, ap2);
-	}
-
-	mgr->last_alloc = *p = dst;
-	mgr->used += needed;
+	if (needed > available) {
+		/* if the space needed can be satisfied by using the current
+		   pool (which could only occur if we tried to use the field's
+		   allocated space and failed), then use that space; otherwise
+		   allocate a new pool
+		*/
+		if (needed > space) {
+			size_t new_size = mgr->size * 2;
+
+			while (new_size < needed)
+				new_size *= 2;
+			
+			if (add_string_pool(mgr, pool_head, new_size))
+				return;
+		}
+
+		target = (*pool_head)->base + mgr->used;
+		vsprintf(target, format, ap2);
+	}
+
+	if (*ptr != target) {
+		mgr->last_alloc = *ptr = target;
+		mgr->used += needed;
+	}
 }
 
 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
 				  struct ast_string_field_pool **pool_head,
-				  const ast_string_field *ptr, const char *format, ...)
+				  ast_string_field *ptr, const char *format, ...)
 {
 	va_list ap1, ap2;
 




More information about the asterisk-commits mailing list