From 7af50da2c9b94f00063877c582c0b34578feb7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 21 Oct 2019 17:56:14 +0300 Subject: [PATCH] bus: Use new GSource dispose function Without this it is possible that we have a GSource with reference count 0 stored in the GstBus that is currently in the process of being destroyed. gst_bus_remove_watch() might then access it, increase its reference count to 1 again, call GSource API on it and then unref it, which will then finalize it a second time. The dispose function allows the GSource to be resurrected until it returned so the above would be safe now. This caused some spurious crashes during shutdown in various applications. --- gst/gstbus.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/gst/gstbus.c b/gst/gstbus.c index 4553288c60..a10b89c917 100644 --- a/gst/gstbus.c +++ b/gst/gstbus.c @@ -852,20 +852,40 @@ no_handler: } } +#if GLIB_CHECK_VERSION(2,63,3) static void -gst_bus_source_finalize (GSource * source) +gst_bus_source_dispose (GSource * source) { GstBusSource *bsource = (GstBusSource *) source; GstBus *bus; bus = bsource->bus; - GST_DEBUG_OBJECT (bus, "finalize source %p", source); + GST_DEBUG_OBJECT (bus, "disposing source %p", source); GST_OBJECT_LOCK (bus); if (bus->priv->signal_watch == source) bus->priv->signal_watch = NULL; GST_OBJECT_UNLOCK (bus); +} +#endif + +static void +gst_bus_source_finalize (GSource * source) +{ + GstBusSource *bsource = (GstBusSource *) source; +#if !GLIB_CHECK_VERSION(2,63,3) + GstBus *bus = bsource->bus; +#endif + + GST_DEBUG_OBJECT (bus, "finalize source %p", source); + +#if !GLIB_CHECK_VERSION(2,63,3) + GST_OBJECT_LOCK (bus); + if (bus->priv->signal_watch == source) + bus->priv->signal_watch = NULL; + GST_OBJECT_UNLOCK (bus); +#endif gst_object_unref (bsource->bus); bsource->bus = NULL; @@ -900,6 +920,9 @@ gst_bus_create_watch (GstBus * bus) sizeof (GstBusSource)); g_source_set_name ((GSource *) source, "GStreamer message bus watch"); +#if GLIB_CHECK_VERSION(2,63,3) + g_source_set_dispose_function ((GSource *) source, gst_bus_source_dispose); +#endif source->bus = gst_object_ref (bus); g_source_add_poll ((GSource *) source, &bus->priv->pollfd);