[vlc-devel] [PATCH 2/8] picture_pool: use a separate API to cancel pending picture requests
Steve Lhomme
robux4 at ycbcr.xyz
Mon Jul 27 15:45:23 CEST 2020
---
include/vlc_picture_pool.h | 27 ++++++++++++++++
src/misc/picture_pool.c | 66 ++++++++++++++++++++++++--------------
2 files changed, 69 insertions(+), 24 deletions(-)
diff --git a/include/vlc_picture_pool.h b/include/vlc_picture_pool.h
index 4f4010f745a..70617aa660a 100644
--- a/include/vlc_picture_pool.h
+++ b/include/vlc_picture_pool.h
@@ -30,6 +30,8 @@
#include <vlc_picture.h>
+typedef struct vlc_cancelable vlc_cancelable;
+
/**
* Picture pool handle
*/
@@ -137,5 +139,30 @@ VLC_USED;
unsigned picture_pool_GetSize(const picture_pool_t *);
+struct vlc_cancelable {
+ vlc_mutex_t lock;
+ vlc_cond_t wait;
+ bool canceled;
+};
+
+/**
+ * Initialize a vlc_cancelable
+ */
+void vlc_cancelable_Init(vlc_cancelable *);
+
+/**
+ * Wait for until the vlc_cancelable is canceled or it's signaled.
+ */
+bool vlc_cancelable_Wait(vlc_cancelable*);
+
+/**
+ * Set the canceled state of the vlc_cancelable.
+ *
+ * This function will also unblock vlc_cancelable_Wait() if the vlc_cancelable
+ * is set to canceled.
+ */
+void vlc_cancelable_SetCanceled(vlc_cancelable*, bool);
+
+
#endif /* VLC_PICTURE_POOL_H */
diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c
index a942a697995..2605b37454f 100644
--- a/src/misc/picture_pool.c
+++ b/src/misc/picture_pool.c
@@ -39,10 +39,8 @@
static_assert ((POOL_MAX & (POOL_MAX - 1)) == 0, "Not a power of two");
struct picture_pool_t {
- vlc_mutex_t lock;
- vlc_cond_t wait;
+ vlc_cancelable cancel;
- bool canceled;
unsigned long long available;
atomic_ushort refs;
unsigned short picture_count;
@@ -75,11 +73,11 @@ static void picture_pool_ReleaseClone(picture_t *clone)
picture_Release(picture);
- vlc_mutex_lock(&pool->lock);
+ vlc_mutex_lock(&pool->cancel.lock);
assert(!(pool->available & (1ULL << offset)));
pool->available |= 1ULL << offset;
- vlc_cond_signal(&pool->wait);
- vlc_mutex_unlock(&pool->lock);
+ vlc_cond_signal(&pool->cancel.wait);
+ vlc_mutex_unlock(&pool->cancel.lock);
picture_pool_Destroy(pool);
}
@@ -107,8 +105,8 @@ picture_pool_t *picture_pool_New(unsigned count, picture_t *const *tab)
if (unlikely(pool == NULL))
return NULL;
- vlc_mutex_init(&pool->lock);
- vlc_cond_init(&pool->wait);
+ vlc_cancelable_Init( &pool->cancel );
+
if (count == POOL_MAX)
pool->available = ~0ULL;
else
@@ -116,7 +114,6 @@ picture_pool_t *picture_pool_New(unsigned count, picture_t *const *tab)
atomic_init(&pool->refs, 1);
pool->picture_count = count;
memcpy(pool->picture, tab, count * sizeof (picture_t *));
- pool->canceled = false;
return pool;
}
@@ -171,7 +168,7 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
{
unsigned long long available;
- vlc_mutex_lock(&pool->lock);
+ vlc_mutex_lock(&pool->cancel.lock);
assert(pool->refs > 0);
available = pool->available;
@@ -179,11 +176,11 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
{
int i = ctz(available);
- if (unlikely(pool->canceled))
+ if (unlikely(pool->cancel.canceled))
break;
pool->available &= ~(1ULL << i);
- vlc_mutex_unlock(&pool->lock);
+ vlc_mutex_unlock(&pool->cancel.lock);
available &= ~(1ULL << i);
picture_t *clone = picture_pool_ClonePicture(pool, i);
@@ -194,28 +191,27 @@ picture_t *picture_pool_Get(picture_pool_t *pool)
return clone;
}
- vlc_mutex_unlock(&pool->lock);
+ vlc_mutex_unlock(&pool->cancel.lock);
return NULL;
}
picture_t *picture_pool_Wait(picture_pool_t *pool)
{
- vlc_mutex_lock(&pool->lock);
+ vlc_mutex_lock(&pool->cancel.lock);
assert(pool->refs > 0);
while (pool->available == 0)
{
- if (pool->canceled)
+ if (!vlc_cancelable_Wait(&pool->cancel))
{
- vlc_mutex_unlock(&pool->lock);
+ vlc_mutex_unlock(&pool->cancel.lock);
return NULL;
}
- vlc_cond_wait(&pool->wait, &pool->lock);
}
int i = ctz(pool->available);
pool->available &= ~(1ULL << i);
- vlc_mutex_unlock(&pool->lock);
+ vlc_mutex_unlock(&pool->cancel.lock);
picture_t *clone = picture_pool_ClonePicture(pool, i);
if (clone != NULL) {
@@ -227,16 +223,38 @@ picture_t *picture_pool_Wait(picture_pool_t *pool)
void picture_pool_Cancel(picture_pool_t *pool, bool canceled)
{
- vlc_mutex_lock(&pool->lock);
assert(pool->refs > 0);
-
- pool->canceled = canceled;
- if (canceled)
- vlc_cond_broadcast(&pool->wait);
- vlc_mutex_unlock(&pool->lock);
+ vlc_cancelable_SetCanceled( &pool->cancel, canceled );
}
unsigned picture_pool_GetSize(const picture_pool_t *pool)
{
return pool->picture_count;
}
+
+
+void vlc_cancelable_Init(vlc_cancelable *cancel)
+{
+ vlc_mutex_init(&cancel->lock);
+ vlc_cond_init(&cancel->wait);
+ cancel->canceled = false;
+}
+
+bool vlc_cancelable_Wait(vlc_cancelable *cancel)
+{
+ vlc_mutex_assert(&cancel->lock);
+ if (cancel->canceled)
+ return false;
+
+ vlc_cond_wait(&cancel->wait, &cancel->lock);
+ return true;
+}
+
+void vlc_cancelable_SetCanceled(vlc_cancelable *cancel, bool canceled)
+{
+ vlc_mutex_lock(&cancel->lock);
+ cancel->canceled = canceled;
+ if (canceled)
+ vlc_cond_broadcast(&cancel->wait);
+ vlc_mutex_unlock(&cancel->lock);
+}
--
2.26.2
More information about the vlc-devel
mailing list