diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h index b618d1965f..780cba3e66 100644 --- a/include/asterisk/frame.h +++ b/include/asterisk/frame.h @@ -560,14 +560,16 @@ void ast_frame_dtor(struct ast_frame *frame); * should be the last operation you do with that frame before freeing * it (or exiting the block, if the frame is on the stack.) */ -struct ast_frame *ast_frisolate(struct ast_frame *fr); +#define ast_frisolate(fr) __ast_frisolate(fr, __FILE__, __LINE__, __PRETTY_FUNCTION__) +struct ast_frame *__ast_frisolate(struct ast_frame *fr, const char *file, int line, const char *func); /*! \brief Copies a frame * \param fr frame to copy * Duplicates a frame -- should only rarely be used, typically frisolate is good enough * \return Returns a frame on success, NULL on error */ -struct ast_frame *ast_frdup(const struct ast_frame *fr); +#define ast_frdup(fr) __ast_frdup(fr, __FILE__, __LINE__, __PRETTY_FUNCTION__) +struct ast_frame *__ast_frdup(const struct ast_frame *fr, const char *file, int line, const char *func); void ast_swapcopy_samples(void *dst, const void *src, int samples); diff --git a/main/frame.c b/main/frame.c index 208c82d2d2..2f4d0860c9 100644 --- a/main/frame.c +++ b/main/frame.c @@ -43,105 +43,25 @@ #include "asterisk/dsp.h" #include "asterisk/file.h" -#if !defined(LOW_MEMORY) -static void frame_cache_cleanup(void *data); - -/*! \brief A per-thread cache of frame headers */ -AST_THREADSTORAGE_CUSTOM(frame_cache, NULL, frame_cache_cleanup); - -/*! - * \brief Maximum ast_frame cache size - * - * In most cases where the frame header cache will be useful, the size - * of the cache will stay very small. However, it is not always the case that - * the same thread that allocates the frame will be the one freeing them, so - * sometimes a thread will never have any frames in its cache, or the cache - * will never be pulled from. For the latter case, we limit the maximum size. - */ -#define FRAME_CACHE_MAX_SIZE 10 - -/*! \brief This is just so ast_frames, a list head struct for holding a list of - * ast_frame structures, is defined. */ -AST_LIST_HEAD_NOLOCK(ast_frames, ast_frame); - -struct ast_frame_cache { - struct ast_frames list; - size_t size; -}; -#endif - struct ast_frame ast_null_frame = { AST_FRAME_NULL, }; -static struct ast_frame *ast_frame_header_new(void) +static struct ast_frame *ast_frame_header_new(const char *file, int line, const char *func) { struct ast_frame *f; -#if !defined(LOW_MEMORY) - struct ast_frame_cache *frames; - - if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) { - if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) { - size_t mallocd_len = f->mallocd_hdr_len; - - memset(f, 0, sizeof(*f)); - f->mallocd_hdr_len = mallocd_len; - frames->size--; - return f; - } - } - if (!(f = ast_calloc_cache(1, sizeof(*f)))) - return NULL; -#else - if (!(f = ast_calloc(1, sizeof(*f)))) + if (!(f = __ast_calloc(1, sizeof(*f), file, line, func))) return NULL; -#endif f->mallocd_hdr_len = sizeof(*f); return f; } -#if !defined(LOW_MEMORY) -static void frame_cache_cleanup(void *data) -{ - struct ast_frame_cache *frames = data; - struct ast_frame *f; - - while ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) - ast_free(f); - - ast_free(frames); -} -#endif - static void __frame_free(struct ast_frame *fr, int cache) { if (!fr->mallocd) return; -#if !defined(LOW_MEMORY) - if (fr->mallocd == AST_MALLOCD_HDR - && cache - && ast_opt_cache_media_frames) { - /* Cool, only the header is malloc'd, let's just cache those for now - * to keep things simple... */ - struct ast_frame_cache *frames; - - frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)); - if (frames && frames->size < FRAME_CACHE_MAX_SIZE) { - if (fr->frametype == AST_FRAME_VOICE - || fr->frametype == AST_FRAME_VIDEO - || fr->frametype == AST_FRAME_IMAGE) { - ao2_cleanup(fr->subclass.format); - } - - AST_LIST_INSERT_HEAD(&frames->list, fr, frame_list); - frames->size++; - return; - } - } -#endif - if (fr->mallocd & AST_MALLOCD_DATA) { if (fr->data.ptr) { ast_free(fr->data.ptr - fr->offset); @@ -185,7 +105,7 @@ void ast_frame_dtor(struct ast_frame *f) * (header, src, data). * On return all components are malloc'ed */ -struct ast_frame *ast_frisolate(struct ast_frame *fr) +struct ast_frame *__ast_frisolate(struct ast_frame *fr, const char *file, int line, const char *func) { struct ast_frame *out; void *newdata; @@ -194,7 +114,7 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) since it is more efficient */ if (fr->mallocd == 0) { - return ast_frdup(fr); + return __ast_frdup(fr, file, line, func); } /* if everything is already malloc'd, we are done */ @@ -205,7 +125,7 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) if (!(fr->mallocd & AST_MALLOCD_HDR)) { /* Allocate a new header if needed */ - if (!(out = ast_frame_header_new())) { + if (!(out = ast_frame_header_new(file, line, func))) { return NULL; } out->frametype = fr->frametype; @@ -291,16 +211,12 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr) return out; } -struct ast_frame *ast_frdup(const struct ast_frame *f) +struct ast_frame *__ast_frdup(const struct ast_frame *f, const char *file, int line, const char *func) { struct ast_frame *out = NULL; int len, srclen = 0; void *buf = NULL; -#if !defined(LOW_MEMORY) - struct ast_frame_cache *frames; -#endif - /* Start with standard stuff */ len = sizeof(*out) + AST_FRIENDLY_OFFSET + f->datalen; /* If we have a source, add space for it */ @@ -313,26 +229,8 @@ struct ast_frame *ast_frdup(const struct ast_frame *f) if (srclen > 0) len += srclen + 1; -#if !defined(LOW_MEMORY) - if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) { - AST_LIST_TRAVERSE_SAFE_BEGIN(&frames->list, out, frame_list) { - if (out->mallocd_hdr_len >= len) { - size_t mallocd_len = out->mallocd_hdr_len; - - AST_LIST_REMOVE_CURRENT(frame_list); - memset(out, 0, sizeof(*out)); - out->mallocd_hdr_len = mallocd_len; - buf = out; - frames->size--; - break; - } - } - AST_LIST_TRAVERSE_SAFE_END; - } -#endif - if (!buf) { - if (!(buf = ast_calloc_cache(1, len))) + if (!(buf = __ast_calloc(1, len, file, line, func))) return NULL; out = buf; out->mallocd_hdr_len = len; @@ -736,3 +634,18 @@ int ast_frame_clear(struct ast_frame *frame) } return 0; } + +/* ABI compatibility */ +#undef ast_frdup +struct ast_frame *ast_frdup(struct ast_frame *fr); +struct ast_frame *ast_frdup(struct ast_frame *fr) +{ + return __ast_frdup(fr, __FILE__, __LINE__, __PRETTY_FUNCTION__); +} + +#undef ast_frisolate +struct ast_frame *ast_frisolate(struct ast_frame *fr); +struct ast_frame *ast_frisolate(struct ast_frame *fr) +{ + return __ast_frisolate(fr, __FILE__, __LINE__, __PRETTY_FUNCTION__); +}