mirror of https://code.videolan.org/videolan/vlc
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:
parent
ed9eaaccd4
commit
1f12ab825b
24
src/libvlc.h
24
src/libvlc.h
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 * );
|
||||
|
||||
|
|
Loading…
Reference in New Issue