[asterisk-commits] mjordan: branch mjordan/12-memorypool r402913 - in /team/mjordan/12-memorypoo...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Nov 20 10:45:51 CST 2013
Author: mjordan
Date: Wed Nov 20 10:45:48 2013
New Revision: 402913
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=402913
Log:
Create branch
Added:
team/mjordan/12-memorypool/
- copied from r402912, branches/12/
Modified:
team/mjordan/12-memorypool/include/asterisk/astobj2.h
team/mjordan/12-memorypool/include/asterisk/channel.h
team/mjordan/12-memorypool/include/asterisk/channel_internal.h
team/mjordan/12-memorypool/main/astobj2.c
team/mjordan/12-memorypool/main/channel.c
team/mjordan/12-memorypool/main/channel_internal_api.c
team/mjordan/12-memorypool/main/stasis_channels.c
Modified: team/mjordan/12-memorypool/include/asterisk/astobj2.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-memorypool/include/asterisk/astobj2.h?view=diff&rev=402913&r1=402912&r2=402913
==============================================================================
--- team/mjordan/12-memorypool/include/asterisk/astobj2.h (original)
+++ team/mjordan/12-memorypool/include/asterisk/astobj2.h Wed Nov 20 10:45:48 2013
@@ -407,6 +407,8 @@
AO2_ALLOC_OPT_LOCK_NOLOCK = (2 << 0),
/*! The ao2 object locking option field mask. */
AO2_ALLOC_OPT_LOCK_MASK = (3 << 0),
+ /*! The ao2 object is part of a memory pool. */
+ AO2_ALLOC_OPT_MEMORY_POOL_ITEM = (4 << 0),
};
/*!
@@ -1933,4 +1935,76 @@
#endif
void ao2_iterator_cleanup(struct ao2_iterator *iter);
+/*!
+ * \brief Construction function for memory pool items
+ *
+ * \param newobj The new object being built
+ *
+ * This function is called one time on each item in a memory pool. It should be
+ * used to create objects in an item that only need to be performed once, such
+ * as string fields.
+ *
+ * \retval 0 on success
+ * \retval any other value on error
+ */
+typedef int (*ao2_constructor_fn)(void *newobj);
+
+/*!
+ * \brief Cleanup function for memory pool items
+ *
+ * \param obj The object being cleaned up
+ *
+ * This function is called when the reference count on an item in the pool
+ * reaches 0. The memory comprising the item is not reclaimed, but references
+ * that the item holds should be released.
+ */
+typedef void (*ao2_cleanup_fn)(void *obj);
+
+struct ao2_memory_pool;
+
+
+/*!
+ * \brief Allocate a memory pool
+ *
+ */
+#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
+
+#define ao2_t_memory_pool_alloc(pool_size, obj_size, ctor_fn, cleanup_fn, dtor_fn, tag) __ao2_memory_pool_alloc_debug((pool_size), (obj_size), (ctor_fn), (cleanup_fn), (dtor_fn), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_memory_pool_alloc(pool_size, obj_size, ctor_fn, cleanup_fn, dtor_fn) __ao2_memory_pool_alloc_debug((pool_size), (obj_size), (ctor_fn), (cleanup_fn), (dtor_fn), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#else
+
+#define ao2_t_memory_pool_alloc(pool_size, obj_size, ctor_fn, cleanup_fn, dtor_fn, tag) __ao2_memory_pool_alloc((pool_size), (obj_size), (ctor_fn), (cleanup_fn), (dtor_fn))
+#define ao2_memory_pool_alloc(pool_size, obj_size, ctor_fn, cleanup_fn, dtor_fn) __ao2_memory_pool_alloc((pool_size), (obj_size), (ctor_fn), (cleanup_fn), (dtor_fn))
+
+#endif
+
+struct ao2_memory_pool *__ao2_memory_pool_alloc_debug(size_t pool_size, size_t obj_size,
+ ao2_constructor_fn ctor_fn, ao2_cleanup_fn cleanup_fn, ao2_destructor_fn dtor_fn,
+ const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
+struct ao2_memory_pool *__ao2_memory_pool_alloc(size_t pool_size, size_t obj_size,
+ ao2_constructor_fn ctor_fn, ao2_cleanup_fn cleanup_fn, ao2_destructor_fn dtor_fn) attribute_warn_unused_result;
+
+/*!
+ * \brief Request an item from the memory pool
+ *
+ * NOTE:
+ */
+
+#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
+
+#define ao2_t_memory_pool_request(pool, tag) __ao2_memory_pool_request_debug((pool), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_memory_pool_request(pool) __ao2_memory_pool_request_debug((pool), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#else
+
+#define ao2_t_memory_pool_request(pool, tag) __ao2_memory_pool_request((pool))
+#define ao2_memory_pool_request(pool) __ao2_memory_pool_request((pool))
+
+#endif
+
+void *__ao2_memory_pool_request_debug(struct ao2_memory_pool *pool, const char *tag,
+ const char *file, int line, const char *func) attribute_warn_unused_result;
+void *__ao2_memory_pool_request(struct ao2_memory_pool *pool) attribute_warn_unused_result;
+
#endif /* _ASTERISK_ASTOBJ2_H */
Modified: team/mjordan/12-memorypool/include/asterisk/channel.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-memorypool/include/asterisk/channel.h?view=diff&rev=402913&r1=402912&r2=402913
==============================================================================
--- team/mjordan/12-memorypool/include/asterisk/channel.h (original)
+++ team/mjordan/12-memorypool/include/asterisk/channel.h Wed Nov 20 10:45:48 2013
@@ -4048,6 +4048,8 @@
struct ast_channel *ast_channel_internal_bridged_channel(const struct ast_channel *chan);
void ast_channel_internal_bridged_channel_set(struct ast_channel *chan, struct ast_channel *value);
+struct ao2_memory_pool *ast_channel_snapshot_pool(struct ast_channel *chan);
+
/*!
* \since 11
* \brief Retreive a comma-separated list of channels for which dialed cause information is available
Modified: team/mjordan/12-memorypool/include/asterisk/channel_internal.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-memorypool/include/asterisk/channel_internal.h?view=diff&rev=402913&r1=402912&r2=402913
==============================================================================
--- team/mjordan/12-memorypool/include/asterisk/channel_internal.h (original)
+++ team/mjordan/12-memorypool/include/asterisk/channel_internal.h Wed Nov 20 10:45:48 2013
@@ -24,4 +24,4 @@
int ast_channel_internal_is_finalized(struct ast_channel *chan);
void ast_channel_internal_cleanup(struct ast_channel *chan);
int ast_channel_internal_setup_topics(struct ast_channel *chan);
-
+int ast_channel_internal_setup_memory_pool(struct ast_channel *chan);
Modified: team/mjordan/12-memorypool/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-memorypool/main/astobj2.c?view=diff&rev=402913&r1=402912&r2=402913
==============================================================================
--- team/mjordan/12-memorypool/main/astobj2.c (original)
+++ team/mjordan/12-memorypool/main/astobj2.c Wed Nov 20 10:45:48 2013
@@ -51,6 +51,9 @@
*/
struct __priv_data {
int ref_counter;
+ /*! Function called by memory pools when object is reclaimed by pool */
+ ao2_cleanup_fn cleanup_fn;
+ /*! Function called when object is destroyed */
ao2_destructor_fn destructor_fn;
/*! User data size for stats */
size_t data_size;
@@ -142,6 +145,9 @@
#define INTERNAL_OBJ_RWLOCK(user_data) \
((struct astobj2_rwlock *) (((char *) (user_data)) - sizeof(struct astobj2_rwlock)))
+
+#define INTERNAL_OBJ_MEMORY_POOL(user_data) \
+ (struct ao2_memory_pool_item *) (((char *) (user_data)) - sizeof(struct ao2_memory_pool_item))
/*!
* \brief convert from a pointer _p to a user-defined object
@@ -431,6 +437,46 @@
return NULL;
}
+/*! \brief An item in a memory pool */
+struct ao2_memory_pool_item {
+ /*! Pointer to the next free item in the pool. When this item is removed
+ * from the pool, this pointer will be NULL. */
+ struct ao2_memory_pool_item *next;
+ /*! Pointer/reference to the pool. When the item is removed, the reference
+ * to the pool is bumped. When not requested, this pointer should not be
+ * used. */
+ struct ao2_memory_pool *pool;
+#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
+ /*! Debug information populated when this object is requested */
+ struct {
+ const char *tag;
+ const char *file;
+ const char *func;
+ int line;
+ } debug;
+#endif
+ /*! The actual ao2 object, with lock */
+ struct astobj2_lock ao2_obj;
+};
+
+/*! \brief A pool of ao2 objects */
+struct ao2_memory_pool {
+ /*! Constructor function for each item in the pool */
+ ao2_constructor_fn constructor_fn;
+ /*! Size (number of items) in the pool */
+ size_t pool_size;
+ /*! Size of the user data in each item in the pool */
+ size_t obj_size;
+ /*! A memory pool to be used if this one is exhausted. */
+ struct ao2_memory_pool *reserve_pool;
+ /*! Pointer to the next free item in the pool */
+ struct ao2_memory_pool_item *first_free_item;
+ /*! Pointer to the last free item in the pool */
+ struct ao2_memory_pool_item *last_free_item;
+ /*! The actual items in the memory pool */
+ struct ao2_memory_pool_item *items[0];
+};
+
static int internal_ao2_ref(void *user_data, int delta, const char *file, int line, const char *func)
{
struct astobj2 *obj = INTERNAL_OBJ(user_data);
@@ -469,8 +515,37 @@
}
/* last reference, destroy the object */
- if (obj->priv_data.destructor_fn != NULL) {
+ if ((obj->priv_data.options & AO2_ALLOC_OPT_MEMORY_POOL_ITEM) == 0
+ && obj->priv_data.destructor_fn != NULL) {
obj->priv_data.destructor_fn(user_data);
+ } else if (obj->priv_data.options & AO2_ALLOC_OPT_MEMORY_POOL_ITEM) {
+ struct ao2_memory_pool_item *item = INTERNAL_OBJ_MEMORY_POOL(user_data);
+
+ if (obj->priv_data.cleanup_fn) {
+ obj->priv_data.cleanup_fn(user_data);
+ }
+
+#if defined(REF_DEBUG) || defined(__AO2_DEBUG_MALLOC)
+ item->debug.tag = NULL;
+ item->debug.file = NULL;
+ item->debug.func = NULL;
+ item->debug.line = 0;
+#endif
+ ast_assert(item->next == NULL);
+ ao2_lock(item->pool);
+ if (item->pool->first_free_item == NULL) {
+ item->pool->first_free_item = item;
+ }
+
+ /* Insert the item at the end of the list */
+ if (item->pool->last_free_item) {
+ item->pool->last_free_item->next = item;
+ }
+ item->pool->last_free_item = item;
+ ao2_unlock(item->pool);
+ ao2_t_ref(item->pool, -1, "Remove pool ref from item");
+
+ return ret;
}
#ifdef AO2_DEBUG
@@ -645,6 +720,232 @@
return internal_ao2_alloc(data_size, destructor_fn, options, __FILE__, __LINE__, __FUNCTION__);
}
+/*! \brief Compute where in a memory pool an item exists, based on its index */
+#define MEMORY_POOL_ITEM(pool, index) \
+ ((struct ao2_memory_pool_item *)((char *)((pool)->items) + (index) * ((pool)->obj_size + sizeof(struct ao2_memory_pool_item))))
+
+/*!
+ * \brief Destructor for a memory pool
+ *
+ * \param obj The memory pool to be destroyed
+ *
+ * This will destroy all items in the memory pool and release any reserved pools
+ * off of this pool. Note that this should never be called until all items in
+ * the memory pool are no longer referenced by consumers.
+ */
+static void memory_pool_dtor(void *obj)
+{
+ struct ao2_memory_pool *pool = obj;
+ int i;
+
+ for (i = 0; i < pool->pool_size; i++) {
+ struct ao2_memory_pool_item *item = MEMORY_POOL_ITEM(pool, i);
+ struct astobj2 *item_obj = (struct astobj2 *)&item->ao2_obj.priv_data;
+
+ if (item_obj->priv_data.destructor_fn) {
+ item_obj->priv_data.destructor_fn(&item->ao2_obj.user_data);
+ }
+
+ item_obj->priv_data.magic = 0;
+ ast_mutex_destroy(&item->ao2_obj.mutex.lock);
+ }
+
+ if (pool->reserve_pool) {
+ ao2_t_ref(pool->reserve_pool, -1, "Release reserve pool");
+ }
+}
+
+/*! \brief Compute the size of a memory pool */
+#define POOL_SIZE(pool, obj_size, pool_size) \
+ sizeof(*(pool)) + (sizeof(struct ao2_memory_pool_item) + (obj_size)) * (pool_size)
+
+/*!
+ * \internal
+ * \brief Initialize an allocated pool
+ *
+ * \param pool The pool to initialize
+ * \param pool_size The number of items in the pool
+ * \param obj_size The size of each item in the pool
+ * \param ctor_fn Constructor function for each item
+ * \param cleanup_fn Cleanup function for each item
+ * \param dtor_fn Destructor function for each item
+ *
+ * \retval The pool on success
+ * \retval NULL on error
+ */
+static struct ao2_memory_pool *internal_ao2_memory_pool_init(struct ao2_memory_pool *pool,
+ size_t pool_size, size_t obj_size, ao2_constructor_fn ctor_fn,
+ ao2_cleanup_fn cleanup_fn, ao2_destructor_fn dtor_fn)
+{
+ struct ao2_memory_pool_item *prev = NULL;
+ int i;
+
+ pool->constructor_fn = ctor_fn;
+ pool->pool_size = pool_size;
+ pool->obj_size = obj_size;
+
+ /* Initialize each object in the pool */
+ for (i = 0; i < pool->pool_size; i++) {
+ struct ao2_memory_pool_item *item = MEMORY_POOL_ITEM(pool, i);
+
+ ast_mutex_init(&item->ao2_obj.mutex.lock);
+
+ item->ao2_obj.priv_data.ref_counter = 0;
+ item->ao2_obj.priv_data.cleanup_fn = cleanup_fn;
+ item->ao2_obj.priv_data.destructor_fn = dtor_fn;
+ item->ao2_obj.priv_data.data_size = pool->obj_size;
+ item->ao2_obj.priv_data.options = AO2_ALLOC_OPT_MEMORY_POOL_ITEM | AO2_ALLOC_OPT_LOCK_MUTEX;
+ item->ao2_obj.priv_data.magic = AO2_MAGIC;
+ if (pool->constructor_fn && pool->constructor_fn(item->ao2_obj.user_data)) {
+ ao2_t_ref(pool, -1, "Dispose of pool due to item init failure");
+ return NULL;
+ }
+
+ item->pool = pool;
+ if (prev) {
+ prev->next = item;
+ }
+ prev = item;
+ }
+
+ pool->first_free_item = MEMORY_POOL_ITEM(pool, 0);
+ pool->last_free_item = MEMORY_POOL_ITEM(pool, (pool->pool_size - 1));
+ return pool;
+}
+
+struct ao2_memory_pool *__ao2_memory_pool_alloc_debug(size_t pool_size, size_t obj_size,
+ ao2_constructor_fn ctor_fn, ao2_cleanup_fn cleanup_fn, ao2_destructor_fn dtor_fn,
+ const char *tag, const char *file, int line, const char *func)
+{
+ struct ao2_memory_pool *pool;
+
+#if defined(REF_DEBUG)
+ pool = __ao2_alloc_debug(POOL_SIZE(pool, obj_size, pool_size),
+ memory_pool_dtor,
+ AO2_ALLOC_OPT_LOCK_MUTEX,
+ tag, file, line, func, 1);
+#elif defined(__AST_DEBUG_MALLOC)
+ pool = __ao2_alloc_debug(POOL_SIZE(pool, obj_size, pool_size),
+ memory_pool_dtor,
+ AO2_ALLOC_OPT_LOCK_MUTEX,
+ tag, file, line, func, 0);
+#else
+ /* We shouldn't get here if not compiled with a debug mode */
+ pool = NULL;
+ ast_assert(0);
+#endif
+ if (!pool) {
+ return NULL;
+ }
+
+ return internal_ao2_memory_pool_init(pool, pool_size, obj_size, ctor_fn,
+ cleanup_fn, dtor_fn);
+}
+
+struct ao2_memory_pool *__ao2_memory_pool_alloc(size_t pool_size, size_t obj_size,
+ ao2_constructor_fn ctor_fn, ao2_cleanup_fn cleanup_fn, ao2_destructor_fn dtor_fn)
+{
+ struct ao2_memory_pool *pool;
+
+ pool = __ao2_alloc(POOL_SIZE(pool, obj_size, pool_size),
+ memory_pool_dtor,
+ AO2_ALLOC_OPT_LOCK_MUTEX);
+ if (!pool) {
+ return NULL;
+ }
+
+ return internal_ao2_memory_pool_init(pool, pool_size, obj_size, ctor_fn,
+ cleanup_fn, dtor_fn);
+}
+
+static void *internal_ao2_memory_pool_request(struct ao2_memory_pool *pool)
+{
+ struct ao2_memory_pool_item *item;
+
+ item = pool->first_free_item;
+ item->ao2_obj.priv_data.ref_counter = 1;
+ ao2_t_ref(item->pool, +1, "Increase pool ref count from item request");
+
+ /* Set up the next item in the pool and remove ourselves from it */
+ pool->first_free_item = item->next;
+ if (pool->last_free_item == item) {
+ pool->last_free_item = NULL;
+ }
+ item->next = NULL;
+
+ return EXTERNAL_OBJ(&item->ao2_obj);
+}
+
+void *__ao2_memory_pool_request_debug(struct ao2_memory_pool *pool, const char *tag,
+ const char *file, int line, const char *func)
+{
+#if defined(REF_DEBUG)
+ int refo;
+#endif
+#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
+ struct ao2_memory_pool_item *item;
+#endif
+ void *user_data;
+
+ if (!pool) {
+ return NULL;
+ }
+
+ if (pool->first_free_item == NULL) {
+ if (!pool->reserve_pool) {
+ pool->reserve_pool = __ao2_memory_pool_alloc_debug(pool->pool_size * 2,
+ pool->obj_size,
+ pool->constructor_fn,
+ MEMORY_POOL_ITEM(pool, 0)->ao2_obj.priv_data.cleanup_fn,
+ MEMORY_POOL_ITEM(pool, 0)->ao2_obj.priv_data.destructor_fn,
+ tag, file, line, func);
+ if (!pool->reserve_pool) {
+ return NULL;
+ }
+ }
+ return __ao2_memory_pool_request_debug(pool->reserve_pool, tag, file, line, func);
+ }
+
+ user_data = internal_ao2_memory_pool_request(pool);
+#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
+ item = INTERNAL_OBJ_MEMORY_POOL(user_data);
+ item->debug.tag = tag;
+ item->debug.file = file;
+ item->debug.func = func;
+ item->debug.line = line;
+#endif
+#if defined(REF_DEBUG)
+ if ((refo = fopen(REF_FILE, "a"))) {
+ fprintf(refo, "%p =1 %s:%d:%s (%s)\n", item, file, line, func, tag);
+ fclose(refo);
+ }
+#endif
+
+ return user_data;
+}
+
+void *__ao2_memory_pool_request(struct ao2_memory_pool *pool)
+{
+ if (!pool) {
+ return NULL;
+ }
+
+ if (pool->first_free_item == NULL) {
+ if (!pool->reserve_pool) {
+ pool->reserve_pool = ao2_memory_pool_alloc(pool->pool_size * 2,
+ pool->obj_size,
+ pool->constructor_fn,
+ MEMORY_POOL_ITEM(pool, 0)->ao2_obj.priv_data.cleanup_fn,
+ MEMORY_POOL_ITEM(pool, 0)->ao2_obj.priv_data.destructor_fn);
+ if (!pool->reserve_pool) {
+ return NULL;
+ }
+ }
+ return __ao2_memory_pool_request(pool->reserve_pool);
+ }
+
+ return internal_ao2_memory_pool_request(pool);
+}
void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name)
{
Modified: team/mjordan/12-memorypool/main/channel.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-memorypool/main/channel.c?view=diff&rev=402913&r1=402912&r2=402913
==============================================================================
--- team/mjordan/12-memorypool/main/channel.c (original)
+++ team/mjordan/12-memorypool/main/channel.c Wed Nov 20 10:45:48 2013
@@ -874,6 +874,10 @@
if (!(tmp = ast_channel_internal_alloc(ast_channel_destructor, linkedid))) {
/* Channel structure allocation failure. */
+ return NULL;
+ }
+ if (ast_channel_internal_setup_memory_pool(tmp)) {
+ ao2_ref(tmp, -1);
return NULL;
}
Modified: team/mjordan/12-memorypool/main/channel_internal_api.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-memorypool/main/channel_internal_api.c?view=diff&rev=402913&r1=402912&r2=402913
==============================================================================
--- team/mjordan/12-memorypool/main/channel_internal_api.c (original)
+++ team/mjordan/12-memorypool/main/channel_internal_api.c Wed Nov 20 10:45:48 2013
@@ -208,6 +208,7 @@
struct timeval sending_dtmf_tv; /*!< The time this channel started sending the current digit. (Invalid if sending_dtmf_digit is zero.) */
struct stasis_cp_single *topics; /*!< Topic for all channel's events */
struct stasis_forward *endpoint_forward; /*!< Subscription for event forwarding to endpoint's topic */
+ struct ao2_memory_pool *snapshot_pool; /*!< Pool of snapshots */
};
/*! \brief The monotonically increasing integer counter for channel uniqueids */
@@ -1313,6 +1314,11 @@
return &chan->flags;
}
+struct ao2_memory_pool *ast_channel_snapshot_pool(struct ast_channel *chan)
+{
+ return chan->snapshot_pool;
+}
+
static int collect_names_cb(void *obj, void *arg, int flags) {
struct ast_control_pvt_cause_code *cause_code = obj;
struct ast_str **str = arg;
@@ -1378,6 +1384,39 @@
}
#define DIALED_CAUSES_BUCKETS 37
+
+static void channel_snapshot_cleanup(void *obj)
+{
+ struct ast_channel_snapshot *snapshot = obj;
+
+ ao2_cleanup(snapshot->manager_vars);
+ snapshot->manager_vars = NULL;
+ ao2_cleanup(snapshot->channel_vars);
+ snapshot->channel_vars = NULL;
+}
+
+static void channel_snapshot_dtor(void *obj)
+{
+ struct ast_channel_snapshot *snapshot = obj;
+
+ ast_string_field_free_memory(snapshot);
+}
+
+static int channel_snapshot_ctor(void *obj)
+{
+ struct ast_channel_snapshot *snapshot = obj;
+
+ return ast_string_field_init(snapshot, 1024);
+}
+
+int ast_channel_internal_setup_memory_pool(struct ast_channel *chan)
+{
+ if (!(chan->snapshot_pool = ao2_memory_pool_alloc(16, sizeof(struct ast_channel_snapshot),
+ channel_snapshot_ctor, channel_snapshot_cleanup, channel_snapshot_dtor))) {
+ return -1;
+ }
+ return 0;
+}
struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const char *linkedid, const char *file, int line, const char *function)
{
@@ -1425,6 +1464,12 @@
chan->dialed_causes = NULL;
}
+ if (chan->snapshot_pool) {
+ ao2_t_ref(chan->snapshot_pool, -1,
+ "Dispose of pool during channel destruction");
+ chan->snapshot_pool = NULL;
+ }
+
ast_string_field_free_memory(chan);
chan->endpoint_forward = stasis_forward_cancel(chan->endpoint_forward);
Modified: team/mjordan/12-memorypool/main/stasis_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/12-memorypool/main/stasis_channels.c?view=diff&rev=402913&r1=402912&r2=402913
==============================================================================
--- team/mjordan/12-memorypool/main/stasis_channels.c (original)
+++ team/mjordan/12-memorypool/main/stasis_channels.c Wed Nov 20 10:45:48 2013
@@ -161,18 +161,9 @@
return strcasecmp(left->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
}
-static void channel_snapshot_dtor(void *obj)
-{
- struct ast_channel_snapshot *snapshot = obj;
-
- ast_string_field_free_memory(snapshot);
- ao2_cleanup(snapshot->manager_vars);
- ao2_cleanup(snapshot->channel_vars);
-}
-
struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *chan)
{
- RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+ struct ast_channel_snapshot *snapshot;
RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
char nativeformats[256];
struct ast_str *write_transpath = ast_str_alloca(256);
@@ -185,8 +176,10 @@
return NULL;
}
- snapshot = ao2_alloc(sizeof(*snapshot), channel_snapshot_dtor);
- if (!snapshot || ast_string_field_init(snapshot, 1024)) {
+ ao2_lock(ast_channel_snapshot_pool(chan));
+ snapshot = ao2_memory_pool_request(ast_channel_snapshot_pool(chan));
+ ao2_unlock(ast_channel_snapshot_pool(chan));
+ if (!snapshot) {
return NULL;
}
@@ -267,7 +260,6 @@
snapshot->channel_vars = ast_channel_get_vars(chan);
snapshot->tech_properties = ast_channel_tech(chan)->properties;
- ao2_ref(snapshot, +1);
return snapshot;
}
More information about the asterisk-commits
mailing list