mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 03:31:05 +00:00
controlbinding: Store object in a thread-safe GWeakRef
g_object_weak_ref() is not thread-safe.
This commit is contained in:
parent
6df88752ee
commit
35a34d2fa8
2 changed files with 50 additions and 16 deletions
|
@ -71,6 +71,11 @@ static void gst_control_binding_finalize (GObject * object);
|
||||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstControlBinding, gst_control_binding,
|
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstControlBinding, gst_control_binding,
|
||||||
GST_TYPE_OBJECT, _do_init);
|
GST_TYPE_OBJECT, _do_init);
|
||||||
|
|
||||||
|
struct _GstControlBindingPrivate
|
||||||
|
{
|
||||||
|
GWeakRef object;
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
@ -86,6 +91,8 @@ gst_control_binding_class_init (GstControlBindingClass * klass)
|
||||||
{
|
{
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
g_type_class_add_private (klass, sizeof (GstControlBindingPrivate));
|
||||||
|
|
||||||
gobject_class->constructor = gst_control_binding_constructor;
|
gobject_class->constructor = gst_control_binding_constructor;
|
||||||
gobject_class->set_property = gst_control_binding_set_property;
|
gobject_class->set_property = gst_control_binding_set_property;
|
||||||
gobject_class->get_property = gst_control_binding_get_property;
|
gobject_class->get_property = gst_control_binding_get_property;
|
||||||
|
@ -108,6 +115,10 @@ gst_control_binding_class_init (GstControlBindingClass * klass)
|
||||||
static void
|
static void
|
||||||
gst_control_binding_init (GstControlBinding * binding)
|
gst_control_binding_init (GstControlBinding * binding)
|
||||||
{
|
{
|
||||||
|
binding->ABI.abi.priv =
|
||||||
|
G_TYPE_INSTANCE_GET_PRIVATE (binding, GST_TYPE_CONTROL_BINDING,
|
||||||
|
GstControlBindingPrivate);
|
||||||
|
g_weak_ref_init (&binding->ABI.abi.priv->object, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GObject *
|
static GObject *
|
||||||
|
@ -116,19 +127,26 @@ gst_control_binding_constructor (GType type, guint n_construct_params,
|
||||||
{
|
{
|
||||||
GstControlBinding *binding;
|
GstControlBinding *binding;
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
GstObject *object;
|
||||||
|
|
||||||
binding =
|
binding =
|
||||||
GST_CONTROL_BINDING (G_OBJECT_CLASS (gst_control_binding_parent_class)
|
GST_CONTROL_BINDING (G_OBJECT_CLASS (gst_control_binding_parent_class)
|
||||||
->constructor (type, n_construct_params, construct_params));
|
->constructor (type, n_construct_params, construct_params));
|
||||||
|
|
||||||
GST_INFO_OBJECT (binding->object, "trying to put property '%s' under control",
|
object = g_weak_ref_get (&binding->ABI.abi.priv->object);
|
||||||
|
if (!object) {
|
||||||
|
GST_WARNING_OBJECT (object, "no object set");
|
||||||
|
return (GObject *) binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_INFO_OBJECT (object, "trying to put property '%s' under control",
|
||||||
binding->name);
|
binding->name);
|
||||||
|
|
||||||
/* check if the object has a property of that name */
|
/* check if the object has a property of that name */
|
||||||
if ((pspec =
|
if ((pspec =
|
||||||
g_object_class_find_property (G_OBJECT_GET_CLASS (binding->object),
|
g_object_class_find_property (G_OBJECT_GET_CLASS (object),
|
||||||
binding->name))) {
|
binding->name))) {
|
||||||
GST_DEBUG_OBJECT (binding->object, " psec->flags : 0x%08x", pspec->flags);
|
GST_DEBUG_OBJECT (object, " psec->flags : 0x%08x", pspec->flags);
|
||||||
|
|
||||||
/* check if this param is witable && controlable && !construct-only */
|
/* check if this param is witable && controlable && !construct-only */
|
||||||
if ((pspec->flags & (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE |
|
if ((pspec->flags & (G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE |
|
||||||
|
@ -136,15 +154,18 @@ gst_control_binding_constructor (GType type, guint n_construct_params,
|
||||||
(G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE)) {
|
(G_PARAM_WRITABLE | GST_PARAM_CONTROLLABLE)) {
|
||||||
binding->pspec = pspec;
|
binding->pspec = pspec;
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (binding->object,
|
GST_WARNING_OBJECT (object,
|
||||||
"property '%s' on class '%s' needs to "
|
"property '%s' on class '%s' needs to "
|
||||||
"be writeable, controlable and not construct_only", binding->name,
|
"be writeable, controlable and not construct_only", binding->name,
|
||||||
G_OBJECT_TYPE_NAME (binding->object));
|
G_OBJECT_TYPE_NAME (object));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (binding->object, "class '%s' has no property '%s'",
|
GST_WARNING_OBJECT (object, "class '%s' has no property '%s'",
|
||||||
G_OBJECT_TYPE_NAME (binding->object), binding->name);
|
G_OBJECT_TYPE_NAME (object), binding->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_object_unref (object);
|
||||||
|
|
||||||
return (GObject *) binding;
|
return (GObject *) binding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,9 +175,10 @@ gst_control_binding_dispose (GObject * object)
|
||||||
GstControlBinding *self = GST_CONTROL_BINDING (object);
|
GstControlBinding *self = GST_CONTROL_BINDING (object);
|
||||||
|
|
||||||
/* we did not took a reference */
|
/* we did not took a reference */
|
||||||
g_object_remove_weak_pointer ((GObject *) self->object,
|
g_object_remove_weak_pointer ((GObject *) self->__object,
|
||||||
(gpointer *) & self->object);
|
(gpointer *) & self->__object);
|
||||||
self->object = NULL;
|
self->__object = NULL;
|
||||||
|
g_weak_ref_clear (&self->ABI.abi.priv->object);
|
||||||
|
|
||||||
((GObjectClass *) gst_control_binding_parent_class)->dispose (object);
|
((GObjectClass *) gst_control_binding_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
@ -180,9 +202,11 @@ gst_control_binding_set_property (GObject * object, guint prop_id,
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_OBJECT:
|
case PROP_OBJECT:
|
||||||
/* do not ref to avoid a ref cycle */
|
/* do not ref to avoid a ref cycle */
|
||||||
self->object = g_value_get_object (value);
|
self->__object = g_value_get_object (value);
|
||||||
g_object_add_weak_pointer ((GObject *) self->object,
|
g_object_add_weak_pointer ((GObject *) self->__object,
|
||||||
(gpointer *) & self->object);
|
(gpointer *) & self->__object);
|
||||||
|
|
||||||
|
g_weak_ref_set (&self->ABI.abi.priv->object, self->__object);
|
||||||
break;
|
break;
|
||||||
case PROP_NAME:
|
case PROP_NAME:
|
||||||
self->name = g_value_dup_string (value);
|
self->name = g_value_dup_string (value);
|
||||||
|
@ -201,7 +225,7 @@ gst_control_binding_get_property (GObject * object, guint prop_id,
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case PROP_OBJECT:
|
case PROP_OBJECT:
|
||||||
g_value_set_object (value, self->object);
|
g_value_take_object (value, g_weak_ref_get (&self->ABI.abi.priv->object));
|
||||||
break;
|
break;
|
||||||
case PROP_NAME:
|
case PROP_NAME:
|
||||||
g_value_set_string (value, self->name);
|
g_value_set_string (value, self->name);
|
||||||
|
|
|
@ -46,6 +46,7 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _GstControlBinding GstControlBinding;
|
typedef struct _GstControlBinding GstControlBinding;
|
||||||
typedef struct _GstControlBindingClass GstControlBindingClass;
|
typedef struct _GstControlBindingClass GstControlBindingClass;
|
||||||
|
typedef struct _GstControlBindingPrivate GstControlBindingPrivate;
|
||||||
|
|
||||||
/* FIXME(2.0): remove, this is unused */
|
/* FIXME(2.0): remove, this is unused */
|
||||||
typedef void (* GstControlBindingConvert) (GstControlBinding *binding, gdouble src_value, GValue *dest_value);
|
typedef void (* GstControlBindingConvert) (GstControlBinding *binding, gdouble src_value, GValue *dest_value);
|
||||||
|
@ -59,17 +60,26 @@ typedef void (* GstControlBindingConvert) (GstControlBinding *binding, gdouble s
|
||||||
*/
|
*/
|
||||||
struct _GstControlBinding {
|
struct _GstControlBinding {
|
||||||
GstObject parent;
|
GstObject parent;
|
||||||
|
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
gchar *name;
|
gchar *name;
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
|
#ifndef GST_DISABLE_DEPRECATED
|
||||||
GstObject *object; /* GstObject owning the property
|
GstObject *object; /* GstObject owning the property
|
||||||
* (== parent when bound) */
|
* (== parent when bound) */
|
||||||
|
#else
|
||||||
|
gpointer __object;
|
||||||
|
#endif
|
||||||
gboolean disabled;
|
gboolean disabled;
|
||||||
|
|
||||||
gpointer _gst_reserved[GST_PADDING];
|
union {
|
||||||
|
struct {
|
||||||
|
GstControlBindingPrivate *priv;
|
||||||
|
} abi;
|
||||||
|
gpointer _gst_reserved[GST_PADDING];
|
||||||
|
} ABI;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue