diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2016-02-29 10:01:50 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2016-02-29 13:41:15 +0200 |
commit | 05700a7082c145057ccc0be763067bcc263239eb (patch) | |
tree | a94fa1b21a71e9fd899a10b8302d64bd17784a69 /gst | |
parent | 15e0f6315f737b673f10f7bfcf47d01be89eedc7 (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.c | 45 |
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; |