summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-10-13 18:20:58 +0200
committerSebastian Dröge <sebastian@centricular.com>2016-10-13 18:25:59 +0200
commit35a34d2fa8a7fd4f2ba7f5808afbfdcc69eade51 (patch)
treed7aec623ccc93b686a7e9eb7f2f8b6674552042d
parent6df88752ee08e0213d001a8b2447fb161d60064c (diff)
controlbinding: Store object in a thread-safe GWeakRef
g_object_weak_ref() is not thread-safe.
-rw-r--r--gst/gstcontrolbinding.c52
-rw-r--r--gst/gstcontrolbinding.h14
2 files changed, 50 insertions, 16 deletions
diff --git a/gst/gstcontrolbinding.c b/gst/gstcontrolbinding.c
index 11bd65d620..e758ad1fb0 100644
--- a/gst/gstcontrolbinding.c
+++ b/gst/gstcontrolbinding.c
@@ -71,6 +71,11 @@ static void gst_control_binding_finalize (GObject * object);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstControlBinding, gst_control_binding,
GST_TYPE_OBJECT, _do_init);
+struct _GstControlBindingPrivate
+{
+ GWeakRef object;
+};
+
enum
{
PROP_0,
@@ -86,6 +91,8 @@ gst_control_binding_class_init (GstControlBindingClass * 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->set_property = gst_control_binding_set_property;
gobject_class->get_property = gst_control_binding_get_property;
@@ -108,6 +115,10 @@ gst_control_binding_class_init (GstControlBindingClass * klass)
static void
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 *
@@ -116,19 +127,26 @@ gst_control_binding_constructor (GType type, guint n_construct_params,
{
GstControlBinding *binding;
GParamSpec *pspec;
+ GstObject *object;
binding =
GST_CONTROL_BINDING (G_OBJECT_CLASS (gst_control_binding_parent_class)
->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);
/* check if the object has a property of that name */
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))) {
- 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 */
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)) {
binding->pspec = pspec;
} else {
- GST_WARNING_OBJECT (binding->object,
+ GST_WARNING_OBJECT (object,
"property '%s' on class '%s' needs to "
"be writeable, controlable and not construct_only", binding->name,
- G_OBJECT_TYPE_NAME (binding->object));
+ G_OBJECT_TYPE_NAME (object));
}
} else {
- GST_WARNING_OBJECT (binding->object, "class '%s' has no property '%s'",
- G_OBJECT_TYPE_NAME (binding->object), binding->name);
+ GST_WARNING_OBJECT (object, "class '%s' has no property '%s'",
+ G_OBJECT_TYPE_NAME (object), binding->name);
}
+
+ gst_object_unref (object);
+
return (GObject *) binding;
}
@@ -154,9 +175,10 @@ gst_control_binding_dispose (GObject * object)
GstControlBinding *self = GST_CONTROL_BINDING (object);
/* we did not took a reference */
- g_object_remove_weak_pointer ((GObject *) self->object,
- (gpointer *) & self->object);
- self->object = NULL;
+ g_object_remove_weak_pointer ((GObject *) self->__object,
+ (gpointer *) & self->__object);
+ self->__object = NULL;
+ g_weak_ref_clear (&self->ABI.abi.priv->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) {
case PROP_OBJECT:
/* do not ref to avoid a ref cycle */
- self->object = g_value_get_object (value);
- g_object_add_weak_pointer ((GObject *) self->object,
- (gpointer *) & self->object);
+ self->__object = g_value_get_object (value);
+ g_object_add_weak_pointer ((GObject *) self->__object,
+ (gpointer *) & self->__object);
+
+ g_weak_ref_set (&self->ABI.abi.priv->object, self->__object);
break;
case PROP_NAME:
self->name = g_value_dup_string (value);
@@ -201,7 +225,7 @@ gst_control_binding_get_property (GObject * object, guint prop_id,
switch (prop_id) {
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;
case PROP_NAME:
g_value_set_string (value, self->name);
diff --git a/gst/gstcontrolbinding.h b/gst/gstcontrolbinding.h
index 2f11f2eb55..9a73d4132b 100644
--- a/gst/gstcontrolbinding.h
+++ b/gst/gstcontrolbinding.h
@@ -46,6 +46,7 @@ G_BEGIN_DECLS
typedef struct _GstControlBinding GstControlBinding;
typedef struct _GstControlBindingClass GstControlBindingClass;
+typedef struct _GstControlBindingPrivate GstControlBindingPrivate;
/* FIXME(2.0): remove, this is unused */
typedef void (* GstControlBindingConvert) (GstControlBinding *binding, gdouble src_value, GValue *dest_value);
@@ -59,17 +60,26 @@ typedef void (* GstControlBindingConvert) (GstControlBinding *binding, gdouble s
*/
struct _GstControlBinding {
GstObject parent;
-
+
/*< public >*/
gchar *name;
GParamSpec *pspec;
/*< private >*/
+#ifndef GST_DISABLE_DEPRECATED
GstObject *object; /* GstObject owning the property
* (== parent when bound) */
+#else
+ gpointer __object;
+#endif
gboolean disabled;
- gpointer _gst_reserved[GST_PADDING];
+ union {
+ struct {
+ GstControlBindingPrivate *priv;
+ } abi;
+ gpointer _gst_reserved[GST_PADDING];
+ } ABI;
};
/**