mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-26 19:01:44 +02:00
avcodec/refstruct: Allow to share pools
To do this, make FFRefStructPool itself refcounted according to the RefStruct API. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
92abc7266b
commit
0c44f63b02
@ -210,7 +210,7 @@ static void pool_free(FFRefStructPool *pool)
|
|||||||
ff_mutex_destroy(&pool->mutex);
|
ff_mutex_destroy(&pool->mutex);
|
||||||
if (pool->free_cb)
|
if (pool->free_cb)
|
||||||
pool->free_cb(pool->opaque);
|
pool->free_cb(pool->opaque);
|
||||||
av_free(pool);
|
av_free(get_refcount(pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pool_free_entry(FFRefStructPool *pool, RefCount *ref)
|
static void pool_free_entry(FFRefStructPool *pool, RefCount *ref)
|
||||||
@ -301,13 +301,22 @@ void *ff_refstruct_pool_get(FFRefStructPool *pool)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
|
/**
|
||||||
|
* Hint: The content of pool_unref() and refstruct_pool_uninit()
|
||||||
|
* could currently be merged; they are only separate functions
|
||||||
|
* in case we would ever introduce weak references.
|
||||||
|
*/
|
||||||
|
static void pool_unref(void *ref)
|
||||||
{
|
{
|
||||||
FFRefStructPool *pool = *poolp;
|
FFRefStructPool *pool = get_userdata(ref);
|
||||||
RefCount *entry;
|
if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1)
|
||||||
|
pool_free(pool);
|
||||||
|
}
|
||||||
|
|
||||||
if (!pool)
|
static void refstruct_pool_uninit(FFRefStructOpaque unused, void *obj)
|
||||||
return;
|
{
|
||||||
|
FFRefStructPool *pool = obj;
|
||||||
|
RefCount *entry;
|
||||||
|
|
||||||
ff_mutex_lock(&pool->mutex);
|
ff_mutex_lock(&pool->mutex);
|
||||||
ff_assert(!pool->uninited);
|
ff_assert(!pool->uninited);
|
||||||
@ -321,11 +330,6 @@ void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
|
|||||||
pool_free_entry(pool, entry);
|
pool_free_entry(pool, entry);
|
||||||
entry = next;
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (atomic_fetch_sub_explicit(&pool->refcount, 1, memory_order_acq_rel) == 1)
|
|
||||||
pool_free(pool);
|
|
||||||
|
|
||||||
*poolp = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FFRefStructPool *ff_refstruct_pool_alloc(size_t size, unsigned flags)
|
FFRefStructPool *ff_refstruct_pool_alloc(size_t size, unsigned flags)
|
||||||
@ -340,11 +344,13 @@ FFRefStructPool *ff_refstruct_pool_alloc_ext_c(size_t size, unsigned flags,
|
|||||||
void (*free_entry_cb)(FFRefStructOpaque opaque, void *obj),
|
void (*free_entry_cb)(FFRefStructOpaque opaque, void *obj),
|
||||||
void (*free_cb)(FFRefStructOpaque opaque))
|
void (*free_cb)(FFRefStructOpaque opaque))
|
||||||
{
|
{
|
||||||
FFRefStructPool *pool = av_mallocz(sizeof(*pool));
|
FFRefStructPool *pool = ff_refstruct_alloc_ext(sizeof(*pool), 0, NULL,
|
||||||
|
refstruct_pool_uninit);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!pool)
|
if (!pool)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
get_refcount(pool)->free = pool_unref;
|
||||||
|
|
||||||
pool->size = size;
|
pool->size = size;
|
||||||
pool->opaque = opaque;
|
pool->opaque = opaque;
|
||||||
@ -371,7 +377,9 @@ FFRefStructPool *ff_refstruct_pool_alloc_ext_c(size_t size, unsigned flags,
|
|||||||
|
|
||||||
err = ff_mutex_init(&pool->mutex, NULL);
|
err = ff_mutex_init(&pool->mutex, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
av_free(pool);
|
// Don't call ff_refstruct_uninit() on pool, as it hasn't been properly
|
||||||
|
// set up and is just a POD right now.
|
||||||
|
av_free(get_refcount(pool));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return pool;
|
return pool;
|
||||||
|
@ -289,6 +289,9 @@ void *ff_refstruct_pool_get(FFRefStructPool *pool);
|
|||||||
* @param poolp pointer to a pointer to either NULL or a pool to be freed.
|
* @param poolp pointer to a pointer to either NULL or a pool to be freed.
|
||||||
* `*poolp` will be set to NULL.
|
* `*poolp` will be set to NULL.
|
||||||
*/
|
*/
|
||||||
void ff_refstruct_pool_uninit(FFRefStructPool **poolp);
|
static inline void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
|
||||||
|
{
|
||||||
|
ff_refstruct_unref(poolp);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* AVCODEC_REFSTRUCT_H */
|
#endif /* AVCODEC_REFSTRUCT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user