[vlc-commits] objects: separate private data from public data

Rémi Denis-Courmont git at videolan.org
Sun Apr 14 21:05:30 CEST 2019


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Apr 14 18:18:56 2019 +0300| [1f12ab825bbd1c964f256cf36a57e1f236d59056] | committer: Rémi Denis-Courmont

objects: separate private data from public data

Allocate the object private data separately - stop relying on alignment
and unconventional pointer arithmetic. This adds (internal) functions
to (de)initialize an object in place.

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

 src/libvlc.h         | 24 ++++++++++++++++++++++++
 src/misc/objects.c   | 44 ++++++++++++++++++++++++--------------------
 src/misc/variables.h |  4 +---
 3 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/src/libvlc.h b/src/libvlc.h
index 0cf4320f70..f7d05116a3 100644
--- a/src/libvlc.h
+++ b/src/libvlc.h
@@ -98,6 +98,30 @@ void vlc_ExitDestroy( vlc_exit_t * );
  */
 
 /**
+ * Initializes a VLC object.
+ *
+ * @param obj storage space for object to initialize [OUT]
+ * @param parent parent object (or NULL to initialize the root) [IN]
+ * @param type_name object type name
+ *
+ * @note The type name pointer must remain valid even after the object is
+ * deinitialized, as it might be passed by address to log message queue.
+ * Using constant string literals is appropriate.
+ *
+ * @retval 0 on success
+ * @retval -1 on (out of memory) error
+ */
+int vlc_object_init(vlc_object_t *obj, vlc_object_t *parent,
+                    const char *type_name);
+
+/**
+ * Deinitializes a VLC object.
+ *
+ * This frees resources allocated by vlc_object_init().
+ */
+void vlc_object_deinit(vlc_object_t *obj);
+
+/**
  * Creates a VLC object.
  *
  * Note that because the object name pointer must remain valid, potentially
diff --git a/src/misc/objects.c b/src/misc/objects.c
index 7ca420c3dc..534fb41ea7 100644
--- a/src/misc/objects.c
+++ b/src/misc/objects.c
@@ -58,24 +58,12 @@
 #define vlc_children_foreach(pos, priv) \
     while (((void)(pos), (void)(priv), 0))
 
-#undef vlc_custom_create
-void *vlc_custom_create (vlc_object_t *parent, size_t length,
-                         const char *typename)
+int vlc_object_init(vlc_object_t *restrict obj, vlc_object_t *parent,
+                    const char *typename)
 {
-    /* NOTE:
-     * VLC objects are laid out as follow:
-     * - first the LibVLC-private per-object data,
-     * - then VLC_COMMON members from vlc_object_t,
-     * - finally, the type-specific data (if any).
-     *
-     * This function initializes the LibVLC and common data,
-     * and zeroes the rest.
-     */
-    assert (length >= sizeof (vlc_object_t));
-
-    vlc_object_internals_t *priv = malloc (sizeof (*priv) + length);
+    vlc_object_internals_t *priv = malloc(sizeof (*priv));
     if (unlikely(priv == NULL))
-        return NULL;
+        return -1;
 
     priv->parent = parent;
     priv->typename = typename;
@@ -84,11 +72,8 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
     vlc_cond_init (&priv->var_wait);
     priv->resources = NULL;
 
-    vlc_object_t *obj = (vlc_object_t *)(priv + 1);
-
     obj->obj.priv = priv;
     obj->obj.force = false;
-    memset (obj + 1, 0, length - sizeof (*obj)); /* type-specific stuff */
 
     if (likely(parent != NULL))
     {
@@ -101,6 +86,19 @@ void *vlc_custom_create (vlc_object_t *parent, size_t length,
         obj->obj.no_interact = false;
     }
 
+    return 0;
+}
+
+void *(vlc_custom_create)(vlc_object_t *parent, size_t length,
+                          const char *typename)
+{
+    assert(length >= sizeof (vlc_object_t));
+
+    vlc_object_t *obj = calloc(length, 1);
+    if (unlikely(obj == NULL || vlc_object_init(obj, parent, typename))) {
+        free(obj);
+        obj = NULL;
+    }
     return obj;
 }
 
@@ -119,7 +117,7 @@ vlc_object_t *(vlc_object_parent)(vlc_object_t *obj)
     return vlc_internals(obj)->parent;
 }
 
-void (vlc_object_delete)(vlc_object_t *obj)
+void vlc_object_deinit(vlc_object_t *obj)
 {
     vlc_object_internals_t *priv = vlc_internals(obj);
 
@@ -135,6 +133,12 @@ void (vlc_object_delete)(vlc_object_t *obj)
     free(priv);
 }
 
+void (vlc_object_delete)(vlc_object_t *obj)
+{
+    vlc_object_deinit(obj);
+    free(obj);
+}
+
 void vlc_object_vaLog(vlc_object_t *obj, int prio, const char *module,
                       const char *file, unsigned line, const char *func,
                       const char *format, va_list ap)
diff --git a/src/misc/variables.h b/src/misc/variables.h
index 63f9d49239..71e5a33449 100644
--- a/src/misc/variables.h
+++ b/src/misc/variables.h
@@ -23,7 +23,6 @@
 #ifndef LIBVLC_VARIABLES_H
 # define LIBVLC_VARIABLES_H 1
 
-# include <stdalign.h>
 # include <vlc_list.h>
 
 struct vlc_res;
@@ -35,7 +34,6 @@ typedef struct vlc_object_internals vlc_object_internals_t;
 
 struct vlc_object_internals
 {
-    alignas (max_align_t) /* ensure vlc_externals() is maximally aligned */
     vlc_object_t *parent; /**< Parent object (or NULL) */
     const char *typename; /**< Object type human-readable name */
 
@@ -49,7 +47,7 @@ struct vlc_object_internals
 };
 
 # define vlc_internals(o) ((o)->obj.priv)
-# define vlc_externals( priv ) ((vlc_object_t *)((priv) + 1))
+# define vlc_externals(priv) (abort(), (void *)(priv))
 
 extern void var_DestroyAll( vlc_object_t * );
 



More information about the vlc-commits mailing list