[vlc-devel] [PATCH 2/3] objects: use vlc_list helpers

RĂ©mi Denis-Courmont remi at remlab.net
Sun Jun 10 20:59:49 CEST 2018


---
 src/misc/objects.c   | 72 +++++++++++++++++++++-----------------------
 src/misc/variables.h |  6 ++--
 2 files changed, 37 insertions(+), 41 deletions(-)

diff --git a/src/misc/objects.c b/src/misc/objects.c
index e00d17001c..f1d28712b1 100644
--- a/src/misc/objects.c
+++ b/src/misc/objects.c
@@ -55,6 +55,10 @@
 #include <limits.h>
 #include <assert.h>
 
+#define vlc_children_foreach(pos, it, priv) \
+    vlc_list_foreach(pos, it, &priv->children, \
+                     vlc_object_internals_t, siblings)
+
 static void PrintObjectPrefix(vlc_object_t *obj, bool last)
 {
     const char *str;
@@ -64,10 +68,11 @@ static void PrintObjectPrefix(vlc_object_t *obj, bool last)
 
     PrintObjectPrefix(obj->obj.parent, false);
 
-    if (vlc_internals(obj)->next != NULL)
-        str = last ? " \xE2\x94\x9C" : " \xE2\x94\x82";
-    else
+    if (vlc_list_is_last(&vlc_internals(obj)->siblings,
+                         &vlc_internals(obj->obj.parent)->children))
         str = last ? " \xE2\x94\x94" : "  ";
+    else
+        str = last ? " \xE2\x94\x9C" : " \xE2\x94\x82";
 
     fputs(str, stdout);
 }
@@ -80,7 +85,7 @@ static void PrintObject(vlc_object_t *obj)
 
     PrintObjectPrefix(obj, true);
     printf("\xE2\x94\x80\xE2\x94%c\xE2\x95\xB4%p %s, %u refs\n",
-           (priv->first != NULL) ? 0xAC : 0x80,
+           vlc_list_is_empty(&priv->children) ? 0x80 : 0xAC,
            (void *)obj, obj->obj.object_type, atomic_load(&priv->refs));
 
     vlc_restorecancel (canc);
@@ -97,10 +102,11 @@ static void DumpStructure(vlc_object_t *obj, unsigned level)
     }
 
     vlc_object_internals_t *priv = vlc_internals(obj);
+    struct vlc_list_it it;
 
     /* NOTE: nested locking here (due to recursive call) */
     vlc_mutex_lock (&vlc_internals(obj)->tree_lock);
-    for (priv = priv->first; priv != NULL; priv = priv->next)
+    vlc_children_foreach(priv, it, priv)
         DumpStructure(vlc_externals(priv), level + 1);
     vlc_mutex_unlock (&vlc_internals(obj)->tree_lock);
 }
@@ -134,12 +140,17 @@ static vlc_object_t *ObjectExists (vlc_object_t *root, void *obj)
 
     vlc_object_internals_t *priv = vlc_internals(root);
     vlc_object_t *ret = NULL;
+    struct vlc_list_it it;
 
     /* NOTE: nested locking here (due to recursive call) */
     vlc_mutex_lock (&vlc_internals(root)->tree_lock);
 
-    for (priv = priv->first; priv != NULL && ret == NULL; priv = priv->next)
+    vlc_children_foreach(priv, it, priv)
+    {
         ret = ObjectExists (vlc_externals (priv), obj);
+        if (ret != NULL)
+            break;
+    }
 
     vlc_mutex_unlock (&vlc_internals(root)->tree_lock);
     return ret;
@@ -197,8 +208,7 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
     vlc_cond_init (&priv->var_wait);
     atomic_init (&priv->refs, 1);
     priv->pf_destructor = NULL;
-    priv->prev = NULL;
-    priv->first = NULL;
+    vlc_list_init(&priv->children);
     vlc_mutex_init (&priv->tree_lock);
     priv->resources = NULL;
 
@@ -220,10 +230,7 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
 
         /* Attach the parent to its child (structure lock needed) */
         vlc_mutex_lock (&papriv->tree_lock);
-        priv->next = papriv->first;
-        if (priv->next != NULL)
-            priv->next->prev = priv;
-        papriv->first = priv;
+        vlc_list_append(&priv->siblings, &papriv->children);
         vlc_mutex_unlock (&papriv->tree_lock);
     }
     else
@@ -233,7 +240,6 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
         obj->obj.flags = 0;
         obj->obj.libvlc = self;
         obj->obj.parent = NULL;
-        priv->next = NULL;
 
         /* TODO: should be in src/libvlc.c */
         int canc = vlc_savecancel ();
@@ -349,11 +355,17 @@ static vlc_object_t *FindName (vlc_object_t *obj, const char *name)
         return vlc_object_hold (obj);
 
     vlc_object_t *found = NULL;
+    struct vlc_list_it it;
+
     /* NOTE: nested locking here (due to recursive call) */
     vlc_mutex_lock (&vlc_internals(obj)->tree_lock);
 
-    for (priv = priv->first; priv != NULL && found == NULL; priv = priv->next)
+    vlc_children_foreach(priv, it, priv)
+    {
         found = FindName (vlc_externals(priv), name);
+        if (found != NULL)
+            break;
+    }
 
     /* NOTE: nested locking here (due to recursive call) */
     vlc_mutex_unlock (&vlc_internals(obj)->tree_lock);
@@ -442,8 +454,8 @@ void vlc_object_release (vlc_object_t *obj)
     {   /* Destroying the root object */
         refs = atomic_fetch_sub (&priv->refs, 1);
         assert (refs == 1); /* nobody to race against in this case */
-
-        assert (priv->first == NULL); /* no children can be left */
+        /* no children can be left */
+        assert(vlc_list_is_empty(&priv->children));
 
         int canc = vlc_savecancel ();
         vlc_object_destroy (obj);
@@ -459,31 +471,14 @@ void vlc_object_release (vlc_object_t *obj)
     assert (refs > 0);
 
     if (likely(refs == 1))
-    {   /* Detach from parent to protect against vlc_object_find_name() */
-        vlc_object_internals_t *prev = priv->prev;
-        vlc_object_internals_t *next = priv->next;
-
-        if (prev != NULL)
-        {
-            assert (prev->next == priv);
-            prev->next = next;
-        }
-        else
-        {
-            assert (papriv->first == priv);
-            papriv->first = next;
-        }
-        if (next != NULL)
-        {
-            assert (next->prev == priv);
-            next->prev = prev;
-        }
-    }
+        /* Detach from parent to protect against vlc_object_find_name() */
+        vlc_list_remove(&priv->siblings);
     vlc_mutex_unlock (&papriv->tree_lock);
 
     if (likely(refs == 1))
     {
-        assert (priv->first == NULL); /* no children can be left */
+        /* no children can be left (because children reference their parent) */
+        assert(vlc_list_is_empty(&priv->children));
 
         int canc = vlc_savecancel ();
         vlc_object_destroy (obj);
@@ -522,9 +517,10 @@ size_t vlc_list_children(vlc_object_t *obj, vlc_object_t **restrict tab,
 {
     vlc_object_internals_t *priv;
     size_t count = 0;
+    struct vlc_list_it it;
 
     vlc_mutex_lock (&vlc_internals(obj)->tree_lock);
-    for (priv = vlc_internals(obj)->first; priv != NULL; priv = priv->next)
+    vlc_children_foreach(priv, it, vlc_internals(obj))
     {
          if (count < max)
              tab[count] = vlc_object_hold(vlc_externals(priv));
diff --git a/src/misc/variables.h b/src/misc/variables.h
index 143a938080..21e403ea13 100644
--- a/src/misc/variables.h
+++ b/src/misc/variables.h
@@ -25,6 +25,7 @@
 
 # include <stdalign.h>
 # include <stdatomic.h>
+# include <vlc_list.h>
 
 struct vlc_res;
 
@@ -48,9 +49,8 @@ struct vlc_object_internals
     vlc_destructor_t pf_destructor;
 
     /* Objects tree structure */
-    vlc_object_internals_t *next;  /* next sibling */
-    vlc_object_internals_t *prev;  /* previous sibling */
-    vlc_object_internals_t *first; /* first child */
+    struct vlc_list siblings;  /**< Siblings list node */
+    struct vlc_list children; /**< Children list */
     vlc_mutex_t tree_lock;
 
     /* Object resources */
-- 
2.17.1



More information about the vlc-devel mailing list