[svn-commits] mnicholson: branch group/newcdr r192428 - in /team/group/newcdr: ./ channels/...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue May 5 12:38:40 CDT 2009


Author: mnicholson
Date: Tue May  5 12:38:36 2009
New Revision: 192428

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=192428
Log:
Merged revisions 192318,192357,192362,192387 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r192318 | kpfleming | 2009-05-05 05:34:19 -0500 (Tue, 05 May 2009) | 5 lines
  
  Properly account for memory allocated for channels and datastores
  
  As in previous commits, when channels are allocated (with ast_channel_alloc) or datastores are allocated (with ast_datastore_alloc) properly account for the memory being owned by the caller, instead of the allocator function itself.
........
  r192357 | kpfleming | 2009-05-05 08:18:21 -0500 (Tue, 05 May 2009) | 5 lines
  
  Correct some flaws in the memory accounting code for stringfields and ao2 objects
  
  Under some conditions, the memory allocation for stringfields and ao2 objects would not have supplied valid file/function names for MALLOC_DEBUG tracking, so this commit corrects that.
........
  r192362 | kpfleming | 2009-05-05 09:17:18 -0500 (Tue, 05 May 2009) | 5 lines
  
  Add a more efficient way of allocating structures that use stringfields
  
  This commit adds an API call that can be used to allocate a structure along with this stringfield storage in a single allocation.
........
  r192387 | file | 2009-05-05 09:22:47 -0500 (Tue, 05 May 2009) | 10 lines
  
  Fix a bug with setting t38pt_udptl at the user or peer level.
  
  If an incoming call authenticated as a user or peer and t38pt_udptl was
  not set to yes in general then no UDPTL session would be present and any
  T38 related things would fail. This commit changes it so that if after
  authenticating T38 is enabled but no UDPTL session is present one will be
  created.
  
  (issue AST-215)
........

Modified:
    team/group/newcdr/   (props changed)
    team/group/newcdr/channels/chan_sip.c
    team/group/newcdr/include/asterisk/astobj2.h
    team/group/newcdr/include/asterisk/channel.h
    team/group/newcdr/include/asterisk/datastore.h
    team/group/newcdr/include/asterisk/stringfields.h
    team/group/newcdr/main/astobj2.c
    team/group/newcdr/main/channel.c
    team/group/newcdr/main/datastore.c
    team/group/newcdr/main/utils.c

Propchange: team/group/newcdr/
------------------------------------------------------------------------------
    automerge = on

Propchange: team/group/newcdr/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue May  5 12:38:36 2009
@@ -1,1 +1,1 @@
-/trunk:1-192296
+/trunk:1-192426

Modified: team/group/newcdr/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/channels/chan_sip.c?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/channels/chan_sip.c (original)
+++ team/group/newcdr/channels/chan_sip.c Tue May  5 12:38:36 2009
@@ -19635,6 +19635,11 @@
 			return 0;
 		}
 
+		/* If T38 is needed but not present, then make it magically appear */
+		if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && !p->udptl) {
+			p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
+		}
+
 		/* We have a succesful authentication, process the SDP portion if there is one */
 		if (find_sdp(req)) {
 			if (process_sdp(p, req, SDP_T38_INITIATE)) {

Modified: team/group/newcdr/include/asterisk/astobj2.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/include/asterisk/astobj2.h?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/include/asterisk/astobj2.h (original)
+++ team/group/newcdr/include/asterisk/astobj2.h Tue May  5 12:38:36 2009
@@ -402,10 +402,15 @@
  * @{
  */
 
-#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
-
-#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_alloc(data_size, destructor_fn)              __ao2_alloc_debug((data_size), (destructor_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#if defined(REF_DEBUG)
+
+#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
+#define ao2_alloc(data_size, destructor_fn)              __ao2_alloc_debug((data_size), (destructor_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
+
+#elif defined(__AST_DEBUG_MALLOC)
+
+#define ao2_t_alloc(data_size, destructor_fn, debug_msg) __ao2_alloc_debug((data_size), (destructor_fn), (debug_msg),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
+#define ao2_alloc(data_size, destructor_fn)              __ao2_alloc_debug((data_size), (destructor_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
 
 #else
 
@@ -414,7 +419,8 @@
 
 #endif
 
-void *__ao2_alloc_debug(const size_t data_size, ao2_destructor_fn destructor_fn, char *tag, char *file, int line, const char *funcname);
+void *__ao2_alloc_debug(const size_t data_size, ao2_destructor_fn destructor_fn, char *tag,
+			const char *file, int line, const char *funcname, int ref_debug);
 void *__ao2_alloc(const size_t data_size, ao2_destructor_fn destructor_fn);
 
 /*! @} */
@@ -698,10 +704,15 @@
  * destructor is set implicitly.
  */
 
-#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
-
-#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_container_alloc(arg1,arg2,arg3)        __ao2_container_alloc_debug((arg1), (arg2), (arg3), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#if defined(REF_DEBUG)
+
+#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
+#define ao2_container_alloc(arg1,arg2,arg3)        __ao2_container_alloc_debug((arg1), (arg2), (arg3), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
+
+#elif defined(__AST_DEBUG_MALLOC)
+
+#define ao2_t_container_alloc(arg1,arg2,arg3,arg4) __ao2_container_alloc_debug((arg1), (arg2), (arg3), (arg4),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
+#define ao2_container_alloc(arg1,arg2,arg3)        __ao2_container_alloc_debug((arg1), (arg2), (arg3), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
 
 #else
 
@@ -714,7 +725,8 @@
 					    ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn);
 struct ao2_container *__ao2_container_alloc_debug(const unsigned int n_buckets,
 						  ao2_hash_fn *hash_fn, ao2_callback_fn *cmp_fn,
-						  char *tag, char *file, int line, const char *funcname);
+						  char *tag, char *file, int line, const char *funcname,
+						  int ref_debug);
 
 /*! \brief
  * Returns the number of elements in a container.

Modified: team/group/newcdr/include/asterisk/channel.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/include/asterisk/channel.h?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/include/asterisk/channel.h (original)
+++ team/group/newcdr/include/asterisk/channel.h Tue May  5 12:38:36 2009
@@ -859,7 +859,7 @@
  * \deprecated You should use the ast_datastore_alloc() generic function instead.
  * \version 1.6.1 deprecated
  */
-struct ast_datastore *ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
+struct ast_datastore * attribute_malloc ast_channel_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
 	__attribute__((deprecated));
 
 /*!
@@ -918,7 +918,17 @@
  * \note By default, new channels are set to the "s" extension
  *       and "default" context.
  */
-struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt, ...) __attribute__((format(printf, 10, 11)));;
+struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 14)))
+	__ast_channel_alloc(int needqueue, int state, const char *cid_num,
+			    const char *cid_name, const char *acctcode,
+			    const char *exten, const char *context,
+			    const char *linkedid, const int amaflag,
+			    const char *file, int line, const char *function,
+			    const char *name_fmt, ...);
+
+#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, ...) \
+	__ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, \
+			    __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
 
 /*! 
  * \brief Create a fake channel structure 

Modified: team/group/newcdr/include/asterisk/datastore.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/include/asterisk/datastore.h?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/include/asterisk/datastore.h (original)
+++ team/group/newcdr/include/asterisk/datastore.h Tue May  5 12:38:36 2009
@@ -65,7 +65,10 @@
  * \param[in] uid unique identifer
  * \version 1.6.1 moved here and renamed from ast_channel_datastore_alloc
  */
-struct ast_datastore *ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid);
+struct ast_datastore * attribute_malloc __ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid,
+							      const char *file, int line, const char *function);
+
+#define ast_datastore_alloc(info, uid) __ast_datastore_alloc(info, uid, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 /*!
  * \brief Free a data store object

Modified: team/group/newcdr/include/asterisk/stringfields.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/include/asterisk/stringfields.h?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/include/asterisk/stringfields.h (original)
+++ team/group/newcdr/include/asterisk/stringfields.h Tue May  5 12:38:36 2009
@@ -138,6 +138,7 @@
 */
 struct ast_string_field_mgr {
 	ast_string_field last_alloc;			/*!< the last field allocated */
+ 	struct ast_string_field_pool *embedded_pool;	/*!< pointer to the embedded pool, if any */
 #if defined(__AST_DEBUG_MALLOC)
 	const char *owner_file;				/*!< filename of owner */
 	const char *owner_func;				/*!< function name of owner */
@@ -244,7 +245,7 @@
 
 /*! \brief free all memory - to be called before destroying the object */
 #define ast_string_field_free_memory(x)	\
-	__ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, NULL, 0, NULL)
+	__ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 /*!
  * \internal
@@ -252,6 +253,30 @@
  */
 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
 			    int needed, const char *file, int lineno, const char *func);
+
+/*!
+ * \brief Allocate a structure with embedded stringfields in a single allocation
+ * \param n Number of structures to allocate (see ast_calloc)
+ * \param type The type of structure to allocate
+ * \param size The number of bytes of space (minimum) to allocate for stringfields to use
+ *
+ * This function will allocate memory for one or more structures that use stringfields, and
+ * also allocate space for the stringfields and initialize the stringfield management
+ * structure embedded in the outer structure.
+ *
+ * \since 1.6.3
+ */
+#define ast_calloc_with_stringfields(n, type, size) \
+	__ast_calloc_with_stringfields(n, sizeof(type), offsetof(type, __field_mgr), offsetof(type, __field_mgr_pool), \
+				       size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/*!
+ * \internal
+ * \brief internal version of ast_calloc_with_stringfields
+ */
+void * attribute_malloc __ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
+						       size_t field_mgr_pool_offset, size_t pool_size, const char *file,
+						       int lineno, const char *func);
 
 /*!
   \internal

Modified: team/group/newcdr/main/astobj2.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/main/astobj2.c?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/main/astobj2.c (original)
+++ team/group/newcdr/main/astobj2.c Tue May  5 12:38:36 2009
@@ -302,7 +302,7 @@
  * We always alloc at least the size of a void *,
  * for debugging purposes.
  */
-static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, char *file, int line, const char *funcname)
+static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, const char *file, int line, const char *funcname)
 {
 	/* allocation */
 	struct astobj2 *obj;
@@ -335,11 +335,12 @@
 	return EXTERNAL_OBJ(obj);
 }
 
-void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, char *tag, char *file, int line, const char *funcname)
+void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, char *tag,
+			const char *file, int line, const char *funcname, int ref_debug)
 {
 	/* allocation */
 	void *obj;
-	FILE *refo = fopen(REF_FILE,"a");
+	FILE *refo = ref_debug ? fopen(REF_FILE,"a") : NULL;
 
 	obj = internal_ao2_alloc(data_size, destructor_fn, file, line, funcname);
 
@@ -357,7 +358,7 @@
 
 void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn)
 {
-	return internal_ao2_alloc(data_size, destructor_fn, NULL, 0, NULL);
+	return internal_ao2_alloc(data_size, destructor_fn, __FILE__, __LINE__, __FUNCTION__);
 }
 
 
@@ -443,13 +444,14 @@
 }
 
 struct ao2_container *__ao2_container_alloc_debug(const unsigned int n_buckets, ao2_hash_fn *hash_fn,
-						  ao2_callback_fn *cmp_fn, char *tag, char *file, int line, const char *funcname)
+						  ao2_callback_fn *cmp_fn, char *tag, char *file, int line,
+						  const char *funcname, int ref_debug)
 {
 	/* XXX maybe consistency check on arguments ? */
 	/* compute the container size */
 	const unsigned int num_buckets = hash_fn ? n_buckets : 1;
 	size_t container_size = sizeof(struct ao2_container) + num_buckets * sizeof(struct bucket);
-	struct ao2_container *c = __ao2_alloc_debug(container_size, container_destruct_debug, tag, file, line, funcname);
+	struct ao2_container *c = __ao2_alloc_debug(container_size, container_destruct_debug, tag, file, line, funcname, ref_debug);
 
 	return internal_ao2_container_alloc(c, num_buckets, hash_fn, cmp_fn);
 }

Modified: team/group/newcdr/main/channel.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/main/channel.c?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/main/channel.c (original)
+++ team/group/newcdr/main/channel.c Tue May  5 12:38:36 2009
@@ -781,13 +781,16 @@
 static void ast_channel_destructor(void *obj);
 
 /*! \brief Create a new channel structure */
-struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const char *linkedid, const int amaflag, const char *name_fmt, ...)
+static struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 0)))
+__ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char *cid_name,
+		       const char *acctcode, const char *exten, const char *context,
+		       const char *linkedid, const int amaflag, const char *file, int line,
+		       const char *function, const char *name_fmt, va_list ap1, va_list ap2)
 {
 	struct ast_channel *tmp;
 	int x;
 	int flags;
 	struct varshead *headp;
-	va_list ap1, ap2;
 
 	/* If shutting down, don't allocate any new channels */
 	if (shutting_down) {
@@ -795,9 +798,19 @@
 		return NULL;
 	}
 
+#if defined(REF_DEBUG)
+	if (!(tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, function, 1))) {
+		return NULL;
+	}
+#elif defined(__AST_DEBUG_MALLOC)
+	if (!(tmp = __ao2_alloc_debug(sizeof(*tmp), ast_channel_destructor, "", file, line, function, 0))) {
+		return NULL;
+	}
+#else
 	if (!(tmp = ao2_alloc(sizeof(*tmp), ast_channel_destructor))) {
 		return NULL;
 	}
+#endif
 
 	if (!(tmp->sched = sched_context_create())) {
 		ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
@@ -909,9 +922,6 @@
 		ast_string_field_set(tmp, linkedid, tmp->uniqueid);
 	}
 
-	tmp->cid.cid_name = ast_strdup(cid_name);
-	tmp->cid.cid_num = ast_strdup(cid_num);
-
 	if (!ast_strlen_zero(name_fmt)) {
 		/* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
 		 * And they all use slightly different formats for their name string.
@@ -920,11 +930,7 @@
 		 * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
 		 * This new function was written so this can be accomplished.
 		 */
-		va_start(ap1, name_fmt);
-		va_start(ap2, name_fmt);
 		ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
-		va_end(ap1);
-		va_end(ap2);
 	}
 
 	/* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
@@ -1000,6 +1006,26 @@
 	}
 
 	return tmp;
+}
+
+struct ast_channel *__ast_channel_alloc(int needqueue, int state, const char *cid_num,
+					const char *cid_name, const char *acctcode,
+					const char *exten, const char *context,
+					const char *linkedid, const int amaflag,
+					const char *file, int line, const char *function,
+					const char *name_fmt, ...)
+{
+	va_list ap1, ap2;
+	struct ast_channel *result;
+
+	va_start(ap1, name_fmt);
+	va_start(ap2, name_fmt);
+	result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
+					linkedid, amaflag, file, line, function, name_fmt, ap1, ap2);
+	va_end(ap1);
+	va_end(ap2);
+
+	return result;
 }
 
 /* only do the minimum amount of work needed here to make a channel
@@ -6743,3 +6769,38 @@
 	ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
 }
 
+/* DO NOT PUT ADDITIONAL FUNCTIONS BELOW THIS BOUNDARY
+ *
+ * ONLY FUNCTIONS FOR PROVIDING BACKWARDS ABI COMPATIBILITY BELONG HERE
+ *
+ */
+
+/* Provide binary compatibility for modules that call ast_channel_alloc() directly;
+ * newly compiled modules will call __ast_channel_alloc() via the macros in channel.h
+ */
+#undef ast_channel_alloc
+struct ast_channel __attribute__((format(printf, 10, 11)))
+	*ast_channel_alloc(int needqueue, int state, const char *cid_num,
+			   const char *cid_name, const char *acctcode,
+			   const char *exten, const char *context,
+			   const char *linkedid, const int amaflag,
+			   const char *name_fmt, ...);
+struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num,
+				      const char *cid_name, const char *acctcode,
+				      const char *exten, const char *context,
+				      const char *linkedid, const int amaflag,
+				      const char *name_fmt, ...)
+{
+	va_list ap1, ap2;
+	struct ast_channel *result;
+
+
+	va_start(ap1, name_fmt);
+	va_start(ap2, name_fmt);
+	result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
+					linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
+	va_end(ap1);
+	va_end(ap2);
+
+	return result;
+}

Modified: team/group/newcdr/main/datastore.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/main/datastore.c?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/main/datastore.c (original)
+++ team/group/newcdr/main/datastore.c Tue May  5 12:38:36 2009
@@ -28,7 +28,8 @@
 #include "asterisk/datastore.h"
 #include "asterisk/utils.h"
 
-struct ast_datastore *ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
+struct ast_datastore *__ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid,
+					    const char *file, int line, const char *function)
 {
 	struct ast_datastore *datastore = NULL;
 
@@ -37,11 +38,15 @@
 		return NULL;
 	}
 
-	/* Allocate memory for datastore and clear it */
-	datastore = ast_calloc(1, sizeof(*datastore));
-	if (!datastore) {
+#if defined(__AST_DEBUG_MALLOC)
+	if (!(datastore = __ast_calloc(1, sizeof(*datastore), file, line, function))) {
 		return NULL;
 	}
+#else
+	if (!(datastore = ast_calloc(1, sizeof(*datastore)))) {
+		return NULL;
+	}
+#endif
 
 	datastore->info = info;
 
@@ -71,3 +76,19 @@
 
 	return res;
 }
+
+/* DO NOT PUT ADDITIONAL FUNCTIONS BELOW THIS BOUNDARY
+ *
+ * ONLY FUNCTIONS FOR PROVIDING BACKWARDS ABI COMPATIBILITY BELONG HERE
+ *
+ */
+
+/* Provide binary compatibility for modules that call ast_datastore_alloc() directly;
+ * newly compiled modules will call __ast_datastore_alloc() via the macros in datastore.h
+ */
+#undef ast_datastore_alloc
+struct ast_datastore *ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid);
+struct ast_datastore *ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
+{
+	return __ast_datastore_alloc(info, uid, __FILE__, __LINE__, __FUNCTION__);
+}

Modified: team/group/newcdr/main/utils.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/newcdr/main/utils.c?view=diff&rev=192428&r1=192427&r2=192428
==============================================================================
--- team/group/newcdr/main/utils.c (original)
+++ team/group/newcdr/main/utils.c Tue May  5 12:38:36 2009
@@ -1530,6 +1530,8 @@
  * size > 0 means initialize the pool list with a pool of given size.
  *	This must be called right after allocating the object.
  * size = 0 means release all pools except the most recent one.
+ *      If the first pool was allocated via embedding in another
+ *      object, that pool will be preserved instead.
  *	This is useful to e.g. reset an object to the initial value.
  * size < 0 means release all pools.
  *	This must be done before destroying the object.
@@ -1559,6 +1561,9 @@
 
 	if (needed < 0) {		/* reset all pools */
 		/* nothing to do */
+	} else if (mgr->embedded_pool) { /* preserve the embedded pool */
+		preserve = mgr->embedded_pool;
+		cur = *pool_head;
 	} else {			/* preserve the last pool */
 		if (*pool_head == NULL) {
 			ast_log(LOG_WARNING, "trying to reset empty pool\n");
@@ -1605,7 +1610,7 @@
 		if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
 			return NULL;
 #else
-		if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL))
+		if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
 			return NULL;
 #endif
 	}
@@ -1736,6 +1741,50 @@
 	va_end(ap1);
 	va_end(ap2);
 }
+
+void *__ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
+				     size_t field_mgr_pool_offset, size_t pool_size, const char *file,
+				     int lineno, const char *func)
+{
+	struct ast_string_field_mgr *mgr;
+	struct ast_string_field_pool *pool;
+	struct ast_string_field_pool **pool_head;
+	size_t pool_size_needed = sizeof(*pool) + pool_size;
+	size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
+	void *allocation;
+	unsigned int x;
+
+#if defined(__AST_DEBUG_MALLOC)	
+	if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
+		return NULL;
+	}
+#else
+	if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
+		return NULL;
+	}
+#endif
+
+	for (x = 0; x < num_structs; x++) {
+		void *base = allocation + (size_to_alloc * x);
+		const char **p;
+
+		mgr = base + field_mgr_offset;
+		pool_head = base + field_mgr_pool_offset;
+		pool = base + struct_size;
+
+		p = (const char **) pool_head + 1;
+		while ((struct ast_string_field_mgr *) p != mgr) {
+			*p++ = __ast_string_field_empty;
+		}
+
+		mgr->embedded_pool = pool;
+		*pool_head = pool;
+		pool->size = size_to_alloc - struct_size - sizeof(*pool);
+	}
+
+	return allocation;
+}
+
 /* end of stringfields support */
 
 AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */




More information about the svn-commits mailing list