[vlc-commits] service_discovery: lock playlist_ServicesDiscoveryKillAll()

Thomas Guillem git at videolan.org
Wed Jan 24 08:46:26 CET 2018


vlc/vlc-3.0 | branch: master | Thomas Guillem <thomas at gllm.fr> | Mon Jan 22 11:06:48 2018 +0100| [992cd83438cbf89d37fe44a66a8f93a768f79103] | committer: Jean-Baptiste Kempf

service_discovery: lock playlist_ServicesDiscoveryKillAll()

This fixes a race condition between playlist_ServicesDiscoveryRemove() and
playlist_ServicesDiscoveryKillAll().

SDs can be removed from any threads by lua plugins.

CD dd542657-7b65-4f66-9741-22f15e0d563e

(cherry picked from commit d9661b8bdcd40331c71963a565c6e1788f474be7)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=992cd83438cbf89d37fe44a66a8f93a768f79103
---

 src/playlist/services_discovery.c | 30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/src/playlist/services_discovery.c b/src/playlist/services_discovery.c
index 39a43badd6..6c2d9072c0 100644
--- a/src/playlist/services_discovery.c
+++ b/src/playlist/services_discovery.c
@@ -147,23 +147,24 @@ int playlist_ServicesDiscoveryAdd(playlist_t *playlist, const char *chain)
     return VLC_SUCCESS;
 }
 
-static void playlist_ServicesDiscoveryInternalRemove(playlist_t *playlist,
-                                                     vlc_sd_internal_t *sds)
+static void playlist_ServicesDiscoveryInternalRemoveLocked(playlist_t *playlist,
+                                                           vlc_sd_internal_t *sds)
 {
     assert(sds->sd != NULL);
-    vlc_sd_Destroy(sds->sd);
 
+    playlist_Unlock(playlist);
+
+    vlc_sd_Destroy(sds->sd);
     /* Remove the sd playlist node if it exists */
     playlist_Lock(playlist);
+
     if (sds->node != NULL)
         playlist_NodeDeleteExplicit(playlist, sds->node,
             PLAYLIST_DELETE_FORCE | PLAYLIST_DELETE_STOP_IF_CURRENT );
-    playlist_Unlock(playlist);
 
     free(sds);
 }
 
-
 int playlist_ServicesDiscoveryRemove(playlist_t *playlist, const char *name)
 {
     playlist_private_t *priv = pl_priv(playlist);
@@ -181,15 +182,18 @@ int playlist_ServicesDiscoveryRemove(playlist_t *playlist, const char *name)
             break;
         }
     }
-    playlist_Unlock(playlist);
 
     if (sds == NULL)
     {
         msg_Warn(playlist, "discovery %s is not loaded", name);
+        playlist_Unlock(playlist);
         return VLC_EGENERIC;
     }
 
-    playlist_ServicesDiscoveryInternalRemove(playlist, sds);
+    playlist_ServicesDiscoveryInternalRemoveLocked(playlist, sds);
+
+    playlist_Unlock(playlist);
+
     return VLC_SUCCESS;
 }
 
@@ -244,8 +248,14 @@ void playlist_ServicesDiscoveryKillAll(playlist_t *playlist)
 {
     playlist_private_t *priv = pl_priv(playlist);
 
-    for (int i = 0; i < priv->i_sds; i++)
-        playlist_ServicesDiscoveryInternalRemove(playlist, priv->pp_sds[i]);
+    playlist_Lock(playlist);
+    while (priv->i_sds > 0)
+    {
+        vlc_sd_internal_t *sds = priv->pp_sds[priv->i_sds - 1];
+        TAB_ERASE(priv->i_sds, priv->pp_sds, priv->i_sds - 1);
+
+        playlist_ServicesDiscoveryInternalRemoveLocked(playlist, sds);
+    }
 
-    TAB_CLEAN(priv->i_sds, priv->pp_sds);
+    playlist_Unlock(playlist);
 }



More information about the vlc-commits mailing list