[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