[vlc-commits] objects: simplify the vlc_list_children() debug function

Rémi Denis-Courmont git at videolan.org
Sun Jun 10 12:11:24 CEST 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Jun  9 17:17:22 2018 +0300| [6e94ac80216e9790c1ccb54fd3e4c03f710be376] | committer: Rémi Denis-Courmont

objects: simplify the vlc_list_children() debug function

This removes vlc_list_release().

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6e94ac80216e9790c1ccb54fd3e4c03f710be376
---

 include/vlc_objects.h                              |  6 +-
 modules/gui/ncurses.c                              | 19 ++++--
 modules/gui/qt/components/complete_preferences.cpp | 23 +++++--
 modules/gui/qt/dialogs/messages.cpp                | 23 +++++--
 src/libvlccore.sym                                 |  1 -
 src/misc/objects.c                                 | 76 +++++++++-------------
 6 files changed, 83 insertions(+), 65 deletions(-)

diff --git a/include/vlc_objects.h b/include/vlc_objects.h
index f619936504..fca73aefe2 100644
--- a/include/vlc_objects.h
+++ b/include/vlc_objects.h
@@ -117,8 +117,7 @@ VLC_API void *vlc_object_create( vlc_object_t *, size_t ) VLC_MALLOC VLC_USED;
 VLC_API vlc_object_t *vlc_object_find_name( vlc_object_t *, const char * ) VLC_USED VLC_DEPRECATED;
 VLC_API void * vlc_object_hold( vlc_object_t * );
 VLC_API void vlc_object_release( vlc_object_t * );
-VLC_API vlc_list_t *vlc_list_children( vlc_object_t * ) VLC_USED;
-VLC_API void vlc_list_release( vlc_list_t * );
+VLC_API size_t vlc_list_children(vlc_object_t *, vlc_object_t **, size_t) VLC_USED;
 VLC_API char *vlc_object_get_name( const vlc_object_t * ) VLC_USED;
 #define vlc_object_get_name(o) vlc_object_get_name(VLC_OBJECT(o))
 
@@ -133,9 +132,6 @@ VLC_API char *vlc_object_get_name( const vlc_object_t * ) VLC_USED;
 #define vlc_object_release(a) \
     vlc_object_release( VLC_OBJECT(a) )
 
-#define vlc_list_children(a) \
-    vlc_list_children( VLC_OBJECT(a) )
-
 VLC_API VLC_MALLOC void *vlc_obj_malloc(vlc_object_t *, size_t);
 VLC_API VLC_MALLOC void *vlc_obj_calloc(vlc_object_t *, size_t, size_t);
 VLC_API VLC_MALLOC char *vlc_obj_strdup(vlc_object_t *, const char *);
diff --git a/modules/gui/ncurses.c b/modules/gui/ncurses.c
index 4b0e0c4d6c..c645f43bf6 100644
--- a/modules/gui/ncurses.c
+++ b/modules/gui/ncurses.c
@@ -713,12 +713,21 @@ static int SubDrawObject(intf_sys_t *sys, int l, vlc_object_t *p_obj, int i_leve
                   p_obj->obj.object_type, name ? name : "", (void *)p_obj);
     free(name);
 
-    vlc_list_t *list = vlc_list_children(p_obj);
-    for (int i = 0; i < list->i_count ; i++) {
-        l = SubDrawObject(sys, l, list->p_values[i].p_address, i_level,
-            (i == list->i_count - 1) ? "`-" : "|-" );
+    size_t count = 0, size;
+    vlc_object_t **tab = NULL;
+
+    do {
+        size = count;
+        tab = xrealloc(tab, size * sizeof (*tab));
+        count = vlc_list_children(p_obj, tab, size);
+    } while (size < count);
+
+    for (size_t i = 0; i < count ; i++) {
+        l = SubDrawObject(sys, l, tab[i], i_level,
+            (i == count - 1) ? "`-" : "|-" );
+        vlc_object_release(tab[i]);
     }
-    vlc_list_release(list);
+    free(tab);
     return l;
 }
 
diff --git a/modules/gui/qt/components/complete_preferences.cpp b/modules/gui/qt/components/complete_preferences.cpp
index bca44457d3..4179bde294 100644
--- a/modules/gui/qt/components/complete_preferences.cpp
+++ b/modules/gui/qt/components/complete_preferences.cpp
@@ -405,10 +405,25 @@ static void populateLoadedSet( QSet<QString> *loaded, vlc_object_t *p_node )
     if ( !EMPTY_STR( name ) ) loaded->insert( QString( name ) );
     free( name );
 
-    vlc_list_t *l = vlc_list_children( p_node );
-    for( int i=0; i < l->i_count; i++ )
-        populateLoadedSet( loaded, (vlc_object_t *)l->p_values[i].p_address );
-    vlc_list_release( l );
+    size_t count = 0, size;
+    vlc_object_t **tab = NULL;
+
+    do
+    {
+        delete[] tab;
+        size = count;
+        tab = new vlc_object_t *[size];
+        count = vlc_list_children(p_node, tab, size);
+    }
+    while (size < count);
+
+    for (size_t i = 0; i < count ; i++)
+    {
+        populateLoadedSet( loaded, tab[i] );
+        vlc_object_release(tab[i]);
+    }
+
+    delete[] tab;
 }
 
 /* Updates the PrefsItemData loaded status to reflect currently
diff --git a/modules/gui/qt/dialogs/messages.cpp b/modules/gui/qt/dialogs/messages.cpp
index c015868244..7f0bf9eb38 100644
--- a/modules/gui/qt/dialogs/messages.cpp
+++ b/modules/gui/qt/dialogs/messages.cpp
@@ -307,10 +307,25 @@ void MessagesDialog::buildTree( QTreeWidgetItem *parentItem,
     free( name );
     item->setExpanded( true );
 
-    vlc_list_t *l = vlc_list_children( p_obj );
-    for( int i=0; i < l->i_count; i++ )
-        buildTree( item, (vlc_object_t *)l->p_values[i].p_address );
-    vlc_list_release( l );
+    size_t count = 0, size;
+    vlc_object_t **tab = NULL;
+
+    do
+    {
+        delete[] tab;
+        size = count;
+        tab = new vlc_object_t *[size];
+        count = vlc_list_children(p_obj, tab, size);
+    }
+    while (size < count);
+
+    for (size_t i = 0; i < count ; i++)
+    {
+        buildTree( item, tab[i] );
+        vlc_object_release(tab[i]);
+    }
+
+    delete[] tab;
 }
 
 void MessagesDialog::updateOrClear()
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 8df3a7ab4a..0c3a070fdb 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -611,7 +611,6 @@ vlc_interrupt_unregister
 vlc_killed
 vlc_join
 vlc_list_children
-vlc_list_release
 vlc_meta_AddExtra
 vlc_meta_CopyExtraNames
 vlc_meta_Delete
diff --git a/src/misc/objects.c b/src/misc/objects.c
index 0d151d78c3..e00d17001c 100644
--- a/src/misc/objects.c
+++ b/src/misc/objects.c
@@ -493,59 +493,43 @@ void vlc_object_release (vlc_object_t *obj)
     }
 }
 
-#undef vlc_list_children
 /**
- * Gets the list of children of an object, and increment their reference
- * count.
- * @return a list (possibly empty) or NULL in case of error.
+ * Lists the children of an object.
+ *
+ * Fills a table of pointers to children object of an object, incrementing the
+ * reference count for each of them.
+ *
+ * @param obj object whose children are to be listed
+ * @param tab base address to hold the list of children [OUT]
+ * @param max size of the table
+ *
+ * @return the actual numer of children (may be larger than requested).
+ *
+ * @warning The list of object can change asynchronously even before the
+ * function returns. The list meant exclusively for debugging and tracing,
+ * not for functional introspection of any kind.
+ *
+ * @warning Objects appear in the object tree early, and disappear late.
+ * Most object properties are not accessible or not defined when the object is
+ * accessed through this function.
+ * For instance, the object cannot be used as a message log target
+ * (because object flags are not accessible asynchronously).
+ * Also type-specific object variables may not have been created yet, or may
+ * already have been deleted.
  */
-vlc_list_t *vlc_list_children( vlc_object_t *obj )
+size_t vlc_list_children(vlc_object_t *obj, vlc_object_t **restrict tab,
+                         size_t max)
 {
-    vlc_list_t *l = malloc (sizeof (*l));
-    if (unlikely(l == NULL))
-        return NULL;
-
-    l->i_count = 0;
-    l->p_values = NULL;
-
     vlc_object_internals_t *priv;
-    unsigned count = 0;
+    size_t count = 0;
 
     vlc_mutex_lock (&vlc_internals(obj)->tree_lock);
-    for (priv = vlc_internals (obj)->first; priv; priv = priv->next)
-         count++;
-
-    if (count > 0)
+    for (priv = vlc_internals(obj)->first; priv != NULL; priv = priv->next)
     {
-        l->p_values = vlc_alloc (count, sizeof (vlc_value_t));
-        if (unlikely(l->p_values == NULL))
-        {
-            vlc_mutex_unlock (&vlc_internals(obj)->tree_lock);
-            free (l);
-            return NULL;
-        }
-        l->i_count = count;
+         if (count < max)
+             tab[count] = vlc_object_hold(vlc_externals(priv));
+         count++;
     }
-
-    unsigned i = 0;
-
-    for (priv = vlc_internals (obj)->first; priv; priv = priv->next)
-        l->p_values[i++].p_address = vlc_object_hold (vlc_externals (priv));
     vlc_mutex_unlock (&vlc_internals(obj)->tree_lock);
-    return l;
-}
-
-/*****************************************************************************
- * vlc_list_release: free a list previously allocated by vlc_list_find
- *****************************************************************************
- * This function decreases the refcount of all objects in the list and
- * frees the list.
- *****************************************************************************/
-void vlc_list_release( vlc_list_t *p_list )
-{
-    for( int i = 0; i < p_list->i_count; i++ )
-        vlc_object_release( p_list->p_values[i].p_address );
-
-    free( p_list->p_values );
-    free( p_list );
+    return count;
 }



More information about the vlc-commits mailing list