Commit 3ca607e8 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

pool: keep reference to pool in each picture

parent 1d2dcf80
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
* *
*****************************************************************************/ *****************************************************************************/
struct picture_gc_sys_t { struct picture_gc_sys_t {
picture_pool_t *pool;
/* Saved release */ /* Saved release */
void (*destroy)(picture_t *); void (*destroy)(picture_t *);
void *destroy_sys; void *destroy_sys;
...@@ -59,12 +61,51 @@ struct picture_pool_t { ...@@ -59,12 +61,51 @@ struct picture_pool_t {
int picture_count; int picture_count;
picture_t **picture; picture_t **picture;
bool *picture_reserved; bool *picture_reserved;
unsigned refs;
vlc_mutex_t lock;
}; };
static void Destroy(picture_t *);
static int Lock(picture_t *); static int Lock(picture_t *);
static void Unlock(picture_t *); static void Unlock(picture_t *);
static void Release(picture_pool_t *pool)
{
bool destroy;
vlc_mutex_lock(&pool->lock);
assert(pool->refs > 0);
destroy = !--pool->refs;
vlc_mutex_unlock(&pool->lock);
if (!destroy)
return;
vlc_mutex_destroy(&pool->lock);
free(pool->picture_reserved);
free(pool->picture);
free(pool);
}
static void DestroyPicture(picture_t *picture)
{
picture_gc_sys_t *gc_sys = picture->gc.p_sys;
picture_pool_t *pool = gc_sys->pool;
Unlock(picture);
if (!atomic_load(&gc_sys->zombie))
return;
/* Picture from an already destroyed pool */
picture->gc.pf_destroy = gc_sys->destroy;
picture->gc.p_sys = gc_sys->destroy_sys;
free(gc_sys);
picture->gc.pf_destroy(picture);
Release(pool);
}
static picture_pool_t *Create(picture_pool_t *master, int picture_count) static picture_pool_t *Create(picture_pool_t *master, int picture_count)
{ {
picture_pool_t *pool = calloc(1, sizeof(*pool)); picture_pool_t *pool = calloc(1, sizeof(*pool));
...@@ -82,6 +123,8 @@ static picture_pool_t *Create(picture_pool_t *master, int picture_count) ...@@ -82,6 +123,8 @@ static picture_pool_t *Create(picture_pool_t *master, int picture_count)
free(pool); free(pool);
return NULL; return NULL;
} }
pool->refs = 1;
vlc_mutex_init(&pool->lock);
return pool; return pool;
} }
...@@ -114,6 +157,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg ...@@ -114,6 +157,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
picture_gc_sys_t *gc_sys = malloc(sizeof(*gc_sys)); picture_gc_sys_t *gc_sys = malloc(sizeof(*gc_sys));
if (unlikely(gc_sys == NULL)) if (unlikely(gc_sys == NULL))
abort(); abort();
gc_sys->pool = pool;
gc_sys->destroy = picture->gc.pf_destroy; gc_sys->destroy = picture->gc.pf_destroy;
gc_sys->destroy_sys = picture->gc.p_sys; gc_sys->destroy_sys = picture->gc.p_sys;
gc_sys->lock = cfg->lock; gc_sys->lock = cfg->lock;
...@@ -124,12 +168,13 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg ...@@ -124,12 +168,13 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
/* Override the garbage collector */ /* Override the garbage collector */
assert(atomic_load(&picture->gc.refcount) == 1); assert(atomic_load(&picture->gc.refcount) == 1);
atomic_init(&picture->gc.refcount, 0); atomic_init(&picture->gc.refcount, 0);
picture->gc.pf_destroy = Destroy; picture->gc.pf_destroy = DestroyPicture;
picture->gc.p_sys = gc_sys; picture->gc.p_sys = gc_sys;
/* */ /* */
pool->picture[i] = picture; pool->picture[i] = picture;
pool->picture_reserved[i] = false; pool->picture_reserved[i] = false;
pool->refs++;
} }
return pool; return pool;
...@@ -219,9 +264,7 @@ void picture_pool_Delete(picture_pool_t *pool) ...@@ -219,9 +264,7 @@ void picture_pool_Delete(picture_pool_t *pool)
picture_Release(picture); picture_Release(picture);
} }
} }
free(pool->picture_reserved); Release(pool);
free(pool->picture);
free(pool);
} }
picture_t *picture_pool_Get(picture_pool_t *pool) picture_t *picture_pool_Get(picture_pool_t *pool)
...@@ -276,22 +319,6 @@ int picture_pool_GetSize(picture_pool_t *pool) ...@@ -276,22 +319,6 @@ int picture_pool_GetSize(picture_pool_t *pool)
return pool->picture_count; return pool->picture_count;
} }
static void Destroy(picture_t *picture)
{
picture_gc_sys_t *gc_sys = picture->gc.p_sys;
Unlock(picture);
if (atomic_load(&gc_sys->zombie))
{ /* Picture from an already destroyed pool */
picture->gc.pf_destroy = gc_sys->destroy;
picture->gc.p_sys = gc_sys->destroy_sys;
free(gc_sys);
picture->gc.pf_destroy(picture);
}
}
static int Lock(picture_t *picture) static int Lock(picture_t *picture)
{ {
picture_gc_sys_t *gc_sys = picture->gc.p_sys; picture_gc_sys_t *gc_sys = picture->gc.p_sys;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment