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.
This commit is contained in:
Rémi Denis-Courmont 2019-04-14 18:18:56 +03:00
parent ed9eaaccd4
commit 1f12ab825b
3 changed files with 49 additions and 23 deletions

View File

@ -97,6 +97,30 @@ void vlc_ExitDestroy( vlc_exit_t * );
* LibVLC objects stuff
*/
/**
* 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.
*

View File

@ -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)

View File

@ -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 * );