GstRTSPMountPoints: Remove any existing factory before adding a new one

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.
This commit is contained in:
Xavier Claessens 2019-09-05 19:51:06 -04:00 committed by GStreamer Merge Bot
parent dd32924eb0
commit f7bbd9dd86

View file

@ -302,6 +302,27 @@ gst_rtsp_mount_points_match (GstRTSPMountPoints * mounts,
return result; 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: * gst_rtsp_mount_points_add_factory:
* @mounts: a #GstRTSPMountPoints * @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); GST_INFO ("adding media factory %p for path %s", factory, path);
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
gst_rtsp_mount_points_remove_factory_unlocked (mounts, path);
g_sequence_append (priv->mounts, item); g_sequence_append (priv->mounts, item);
priv->dirty = TRUE; priv->dirty = TRUE;
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
@ -350,27 +372,15 @@ gst_rtsp_mount_points_remove_factory (GstRTSPMountPoints * mounts,
const gchar * path) const gchar * path)
{ {
GstRTSPMountPointsPrivate *priv; GstRTSPMountPointsPrivate *priv;
DataItem item;
GSequenceIter *iter;
g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts)); g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
g_return_if_fail (path != NULL); g_return_if_fail (path != NULL);
priv = mounts->priv; priv = mounts->priv;
item.path = (gchar *) path;
GST_INFO ("removing media factory for path %s", path); GST_INFO ("removing media factory for path %s", path);
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
if (priv->dirty) { gst_rtsp_mount_points_remove_factory_unlocked (mounts, path);
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;
}
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
} }