summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2016-02-29 10:01:50 +0200
committerSebastian Dröge <sebastian@centricular.com>2016-02-29 13:41:15 +0200
commit05700a7082c145057ccc0be763067bcc263239eb (patch)
treea94fa1b21a71e9fd899a10b8302d64bd17784a69 /gst
parent15e0f6315f737b673f10f7bfcf47d01be89eedc7 (diff)
bus: Make sure to remove the GPollFD from the GSources when destroying the bus
Otherwise the GSource can look into our already destroyed bus where the GPollFD is stored. https://bugzilla.gnome.org/show_bug.cgi?id=762849
Diffstat (limited to 'gst')
-rw-r--r--gst/gstbus.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/gst/gstbus.c b/gst/gstbus.c
index d24a935ee..294c7d322 100644
--- a/gst/gstbus.c
+++ b/gst/gstbus.c
@@ -119,6 +119,8 @@ struct _GstBusPrivate
gboolean enable_async;
GstPoll *poll;
GPollFD pollfd;
+
+ GList *sources;
};
#define gst_bus_parent_class parent_class
@@ -233,6 +235,7 @@ gst_bus_dispose (GObject * object)
if (bus->priv->queue) {
GstMessage *message;
+ GList *l;
g_mutex_lock (&bus->priv->queue_lock);
do {
@@ -245,6 +248,13 @@ gst_bus_dispose (GObject * object)
g_mutex_unlock (&bus->priv->queue_lock);
g_mutex_clear (&bus->priv->queue_lock);
+ GST_OBJECT_LOCK (bus);
+ for (l = bus->priv->sources; l; l = l->next)
+ g_source_remove_poll (l->data, &bus->priv->pollfd);
+ g_list_free (bus->priv->sources);
+ bus->priv->sources = NULL;
+ GST_OBJECT_UNLOCK (bus);
+
if (bus->priv->poll)
gst_poll_free (bus->priv->poll);
bus->priv->poll = NULL;
@@ -833,6 +843,7 @@ gst_bus_source_finalize (GSource * source)
GST_OBJECT_LOCK (bus);
if (bus->priv->signal_watch == source)
bus->priv->signal_watch = NULL;
+ bus->priv->sources = g_list_remove (bus->priv->sources, source);
GST_OBJECT_UNLOCK (bus);
g_object_unref (bus);
@@ -847,6 +858,26 @@ static GSourceFuncs gst_bus_source_funcs = {
gst_bus_source_finalize
};
+static GSource *
+gst_bus_create_watch_unlocked (GstBus * bus)
+{
+ GstBusSource *source;
+
+ g_return_val_if_fail (GST_IS_BUS (bus), NULL);
+ g_return_val_if_fail (bus->priv->poll != NULL, NULL);
+
+ source = (GstBusSource *) g_source_new (&gst_bus_source_funcs,
+ sizeof (GstBusSource));
+
+ g_source_set_name ((GSource *) source, "GStreamer message bus watch");
+
+ g_weak_ref_init (&source->bus_ref, (GObject *) bus);
+ bus->priv->sources = g_list_prepend (bus->priv->sources, source);
+ g_source_add_poll ((GSource *) source, &bus->priv->pollfd);
+
+ return (GSource *) source;
+}
+
/**
* gst_bus_create_watch:
* @bus: a #GstBus to create the watch for
@@ -860,18 +891,14 @@ static GSourceFuncs gst_bus_source_funcs = {
GSource *
gst_bus_create_watch (GstBus * bus)
{
- GstBusSource *source;
+ GSource *source;
g_return_val_if_fail (GST_IS_BUS (bus), NULL);
g_return_val_if_fail (bus->priv->poll != NULL, NULL);
- source = (GstBusSource *) g_source_new (&gst_bus_source_funcs,
- sizeof (GstBusSource));
-
- g_source_set_name ((GSource *) source, "GStreamer message bus watch");
-
- g_weak_ref_init (&source->bus_ref, (GObject *) bus);
- g_source_add_poll ((GSource *) source, &bus->priv->pollfd);
+ GST_OBJECT_LOCK (bus);
+ source = gst_bus_create_watch_unlocked (bus);
+ GST_OBJECT_UNLOCK (bus);
return (GSource *) source;
}
@@ -891,7 +918,7 @@ gst_bus_add_watch_full_unlocked (GstBus * bus, gint priority,
return 0;
}
- source = gst_bus_create_watch (bus);
+ source = gst_bus_create_watch_unlocked (bus);
if (!source) {
g_critical ("Creating bus watch failed");
return 0;