mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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
This commit is contained in:
parent
15e0f6315f
commit
05700a7082
1 changed files with 36 additions and 9 deletions
45
gst/gstbus.c
45
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;
|
||||
|
|
Loading…
Reference in a new issue