GstRTSPMountPoints: Remove any existing factory before adding a new one
authorXavier Claessens <xavier.claessens@collabora.com>
Thu, 5 Sep 2019 23:51:06 +0000 (19:51 -0400)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 4 Nov 2019 12:01:09 +0000 (12:01 +0000)
The documentation of gst_rtsp_mount_points_add_factory() says "Any
previous mount point will be freed" which was true when it was
implemented using a GHashTable. But in 2012 it got rewrote using a
GSequence and since then it could have 2 factories for the same path.
Which one gets used is random, depending on the sorting order of 2
identical items.

gst/rtsp-server/rtsp-mount-points.c

index 7679485..1011983 100644 (file)
@@ -302,6 +302,27 @@ gst_rtsp_mount_points_match (GstRTSPMountPoints * mounts,
   return result;
 }
 
+static void
+gst_rtsp_mount_points_remove_factory_unlocked (GstRTSPMountPoints * mounts,
+    const gchar * path)
+{
+  GstRTSPMountPointsPrivate *priv = mounts->priv;
+  DataItem item;
+  GSequenceIter *iter;
+
+  item.path = (gchar *) path;
+
+  if (priv->dirty) {
+    g_sequence_sort (priv->mounts, data_item_compare, mounts);
+    priv->dirty = FALSE;
+  }
+  iter = g_sequence_lookup (priv->mounts, &item, data_item_compare, mounts);
+  if (iter) {
+    g_sequence_remove (iter);
+    priv->dirty = TRUE;
+  }
+}
+
 /**
  * gst_rtsp_mount_points_add_factory:
  * @mounts: a #GstRTSPMountPoints
@@ -333,6 +354,7 @@ gst_rtsp_mount_points_add_factory (GstRTSPMountPoints * mounts,
   GST_INFO ("adding media factory %p for path %s", factory, path);
 
   g_mutex_lock (&priv->lock);
+  gst_rtsp_mount_points_remove_factory_unlocked (mounts, path);
   g_sequence_append (priv->mounts, item);
   priv->dirty = TRUE;
   g_mutex_unlock (&priv->lock);
@@ -350,27 +372,15 @@ gst_rtsp_mount_points_remove_factory (GstRTSPMountPoints * mounts,
     const gchar * path)
 {
   GstRTSPMountPointsPrivate *priv;
-  DataItem item;
-  GSequenceIter *iter;
 
   g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
   g_return_if_fail (path != NULL);
 
   priv = mounts->priv;
 
-  item.path = (gchar *) path;
-
   GST_INFO ("removing media factory for path %s", path);
 
   g_mutex_lock (&priv->lock);
-  if (priv->dirty) {
-    g_sequence_sort (priv->mounts, data_item_compare, mounts);
-    priv->dirty = FALSE;
-  }
-  iter = g_sequence_lookup (priv->mounts, &item, data_item_compare, mounts);
-  if (iter) {
-    g_sequence_remove (iter);
-    priv->dirty = TRUE;
-  }
+  gst_rtsp_mount_points_remove_factory_unlocked (mounts, path);
   g_mutex_unlock (&priv->lock);
 }