summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim-Philipp Müller <tim.muller@collabora.co.uk>2009-05-31 20:27:40 (GMT)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>2009-05-31 20:30:18 (GMT)
commitd9df74ea3e49664b474c8dda35e39e6c4fcacd7c (patch)
tree12a592996b9156026eac8b1d5a07508523986876
parent249b9b9aa4db2b35a3d39f895c74e563d3bd457d (diff)
identity: hack around g_object_notify() bug by protecting it with a lock
Out-of-band events might lead to us calling g_object_notify() from a non-streaming thread, which can cause crashes if g_object_notify() is being called from the streaming thread at the same time. See #554460.
-rw-r--r--plugins/elements/gstidentity.c22
-rw-r--r--plugins/elements/gstidentity.h1
2 files changed, 20 insertions, 3 deletions
diff --git a/plugins/elements/gstidentity.c b/plugins/elements/gstidentity.c
index 8385ea2..dfb01ac 100644
--- a/plugins/elements/gstidentity.c
+++ b/plugins/elements/gstidentity.c
@@ -137,6 +137,7 @@ gst_identity_finalize (GObject * object)
identity = GST_IDENTITY (object);
g_free (identity->last_message);
+ g_static_rec_mutex_free (&identity->notify_lock);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -289,6 +290,21 @@ gst_identity_init (GstIdentity * identity, GstIdentityClass * g_class)
identity->dump = DEFAULT_DUMP;
identity->last_message = NULL;
identity->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
+ g_static_rec_mutex_init (&identity->notify_lock);
+}
+
+static void
+gst_identity_notify_last_message (GstIdentity * identity)
+{
+ /* FIXME: this hacks around a bug in GLib/GObject: doing concurrent
+ * g_object_notify() on the same object might lead to crashes, see
+ * http://bugzilla.gnome.org/show_bug.cgi?id=166020#c60 and follow-ups.
+ * So we really don't want to do a g_object_notify() here for out-of-band
+ * events with the streaming thread possibly also doing a g_object_notify()
+ * for an in-band buffer or event. */
+ g_static_rec_mutex_lock (&identity->notify_lock);
+ g_object_notify ((GObject *) identity, "last_message");
+ g_static_rec_mutex_unlock (&identity->notify_lock);
}
static gboolean
@@ -318,7 +334,7 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
g_free (sstr);
GST_OBJECT_UNLOCK (identity);
- g_object_notify (G_OBJECT (identity), "last_message");
+ gst_identity_notify_last_message (identity);
}
if (identity->single_segment
@@ -561,7 +577,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf),
GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf);
GST_OBJECT_UNLOCK (identity);
- g_object_notify (G_OBJECT (identity), "last-message");
+ gst_identity_notify_last_message (identity);
}
/* return DROPPED to basetransform. */
return GST_BASE_TRANSFORM_FLOW_DROPPED;
@@ -585,7 +601,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
GST_BUFFER_FLAGS (buf), buf);
GST_OBJECT_UNLOCK (identity);
- g_object_notify (G_OBJECT (identity), "last-message");
+ gst_identity_notify_last_message (identity);
}
if (identity->datarate > 0) {
diff --git a/plugins/elements/gstidentity.h b/plugins/elements/gstidentity.h
index fabc667..c60297d 100644
--- a/plugins/elements/gstidentity.h
+++ b/plugins/elements/gstidentity.h
@@ -73,6 +73,7 @@ struct _GstIdentity {
gchar *last_message;
guint64 offset;
gboolean signal_handoffs;
+ GStaticRecMutex notify_lock;
};
struct _GstIdentityClass {