bus: Make removing of signal/bus watches thread-safe
authorSebastian Dröge <sebastian@centricular.com>
Fri, 15 Feb 2019 11:23:37 +0000 (13:23 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 15 Feb 2019 11:23:37 +0000 (13:23 +0200)
Between getting the GSource with the mutex and destroying it, something
else might've destroyed it already and we would have a dangling pointer.

Keep an additional reference just in case.

gst/gstbus.c

index 15e14e3dc622ab6bb5619677e637f09478e5e61b..cddaf390b864f64c44a1839b19e57afe6feb1f38 100644 (file)
@@ -1044,7 +1044,7 @@ gst_bus_add_watch (GstBus * bus, GstBusFunc func, gpointer user_data)
 gboolean
 gst_bus_remove_watch (GstBus * bus)
 {
-  GSource *watch_id;
+  GSource *source;
 
   g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
 
@@ -1061,11 +1061,15 @@ gst_bus_remove_watch (GstBus * bus)
     goto error;
   }
 
-  watch_id = bus->priv->signal_watch;
+  source =
+      bus->priv->signal_watch ? g_source_ref (bus->priv->signal_watch) : NULL;
 
   GST_OBJECT_UNLOCK (bus);
 
-  g_source_destroy (watch_id);
+  if (source) {
+    g_source_destroy (source);
+    g_source_unref (source);
+  }
 
   return TRUE;
 
@@ -1459,13 +1463,16 @@ gst_bus_remove_signal_watch (GstBus * bus)
   GST_DEBUG_OBJECT (bus, "removing signal watch %u",
       g_source_get_id (bus->priv->signal_watch));
 
-  source = bus->priv->signal_watch;
+  source =
+      bus->priv->signal_watch ? g_source_ref (bus->priv->signal_watch) : NULL;
 
 done:
   GST_OBJECT_UNLOCK (bus);
 
-  if (source)
+  if (source) {
     g_source_destroy (source);
+    g_source_unref (source);
+  }
 
   return;