[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