[vlc-commits] pool: keep reference to pool in each picture
Rémi Denis-Courmont
git at videolan.org
Wed Oct 29 20:27:50 CET 2014
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Oct 27 21:16:09 2014 +0200| [3ca607e89889c99fa22db208fa46df95033ce3bf] | committer: Rémi Denis-Courmont
pool: keep reference to pool in each picture
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3ca607e89889c99fa22db208fa46df95033ce3bf
---
src/misc/picture_pool.c | 69 ++++++++++++++++++++++++++++++++---------------
1 file changed, 48 insertions(+), 21 deletions(-)
diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c
index 86b30ac..3fb8a69 100644
--- a/src/misc/picture_pool.c
+++ b/src/misc/picture_pool.c
@@ -38,6 +38,8 @@
*
*****************************************************************************/
struct picture_gc_sys_t {
+ picture_pool_t *pool;
+
/* Saved release */
void (*destroy)(picture_t *);
void *destroy_sys;
@@ -59,12 +61,51 @@ struct picture_pool_t {
int picture_count;
picture_t **picture;
bool *picture_reserved;
+
+ unsigned refs;
+ vlc_mutex_t lock;
};
-static void Destroy(picture_t *);
static int Lock(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)
{
picture_pool_t *pool = calloc(1, sizeof(*pool));
@@ -82,6 +123,8 @@ static picture_pool_t *Create(picture_pool_t *master, int picture_count)
free(pool);
return NULL;
}
+ pool->refs = 1;
+ vlc_mutex_init(&pool->lock);
return pool;
}
@@ -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));
if (unlikely(gc_sys == NULL))
abort();
+ gc_sys->pool = pool;
gc_sys->destroy = picture->gc.pf_destroy;
gc_sys->destroy_sys = picture->gc.p_sys;
gc_sys->lock = cfg->lock;
@@ -124,12 +168,13 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
/* Override the garbage collector */
assert(atomic_load(&picture->gc.refcount) == 1);
atomic_init(&picture->gc.refcount, 0);
- picture->gc.pf_destroy = Destroy;
+ picture->gc.pf_destroy = DestroyPicture;
picture->gc.p_sys = gc_sys;
/* */
pool->picture[i] = picture;
pool->picture_reserved[i] = false;
+ pool->refs++;
}
return pool;
@@ -219,9 +264,7 @@ void picture_pool_Delete(picture_pool_t *pool)
picture_Release(picture);
}
}
- free(pool->picture_reserved);
- free(pool->picture);
- free(pool);
+ Release(pool);
}
picture_t *picture_pool_Get(picture_pool_t *pool)
@@ -276,22 +319,6 @@ int picture_pool_GetSize(picture_pool_t *pool)
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)
{
picture_gc_sys_t *gc_sys = picture->gc.p_sys;
More information about the vlc-commits
mailing list