diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2019-10-21 17:56:14 +0300 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2019-12-04 08:24:04 +0000 |
commit | 7af50da2c9b94f00063877c582c0b34578feb7b5 (patch) | |
tree | 76378d93a148e22381d03c99716623673fdf9619 | |
parent | 4a554a2a68e6e7b7d062dc7caf37a52a13e35d82 (diff) | |
download | gstreamer-7af50da2c9b94f00063877c582c0b34578feb7b5.tar.gz |
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.
-rw-r--r-- | gst/gstbus.c | 25 |
1 files changed, 24 insertions, 1 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, "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); |