[vlc-devel] [PATCH 1/4] playlist: add refcount

Romain Vimont rom1v at videolabs.io
Thu Aug 20 17:44:20 CEST 2020


For now, there is only one playlist, with a well-defined lifetime (owned
by the libvlc instance).

To support several playlists which could be added and removed, add a
refcount so that the ownership can be shared.
---
 include/vlc_interface.h |  5 +++-
 include/vlc_playlist.h  | 13 +++++++--
 src/libvlc.c            |  2 +-
 src/libvlccore.sym      |  3 +-
 src/playlist/playlist.c | 15 +++++++++-
 src/playlist/playlist.h |  3 ++
 src/playlist/test.c     | 62 ++++++++++++++++++++---------------------
 7 files changed, 65 insertions(+), 38 deletions(-)

diff --git a/include/vlc_interface.h b/include/vlc_interface.h
index 021314c37b..436f2c8701 100644
--- a/include/vlc_interface.h
+++ b/include/vlc_interface.h
@@ -92,7 +92,10 @@ VLC_API int intf_Create( libvlc_int_t *, const char * );
 VLC_API void libvlc_Quit( libvlc_int_t * );
 
 /**
- * Recover the main playlist from an interface module
+ * Return a pointer to the main playlist from an interface module
+ *
+ * Calling this method does not increment the playlist refcount. The playlist
+ * is guaranteed to exist until the libvlc instance is destroyed.
  *
  * @return the main playlist (can't be NULL)
  */
diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h
index 5b35cf6ac9..2c11cf8fd7 100644
--- a/include/vlc_playlist.h
+++ b/include/vlc_playlist.h
@@ -334,12 +334,19 @@ VLC_API VLC_USED vlc_playlist_t *
 vlc_playlist_New(vlc_object_t *parent);
 
 /**
- * Delete a playlist.
+ * Increment the playlist refcount.
+ */
+VLC_API void
+vlc_playlist_Hold(vlc_playlist_t *);
+
+/**
+ * Decrement the playlist refcount.
  *
- * All playlist items are released, and listeners are removed and destroyed.
+ * If it reaches 0 (it was the last reference), the playlist is deleted: all
+ * playlist items are released, and listeners are removed and destroyed.
  */
 VLC_API void
-vlc_playlist_Delete(vlc_playlist_t *);
+vlc_playlist_Release(vlc_playlist_t *);
 
 /**
  * Lock the playlist/player.
diff --git a/src/libvlc.c b/src/libvlc.c
index c1dcde276d..3e6356598b 100644
--- a/src/libvlc.c
+++ b/src/libvlc.c
@@ -377,7 +377,7 @@ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
         input_preparser_Delete(priv->parser);
 
     if (priv->main_playlist)
-        vlc_playlist_Delete(priv->main_playlist);
+        vlc_playlist_Release(priv->main_playlist);
 
     if ( priv->p_media_library )
         libvlc_MlRelease( priv->p_media_library );
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index ed43c17715..f2aaba339d 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -898,7 +898,8 @@ vlc_playlist_item_GetId
 vlc_playlist_view_Count
 vlc_playlist_view_Get
 vlc_playlist_New
-vlc_playlist_Delete
+vlc_playlist_Hold
+vlc_playlist_Release
 vlc_playlist_Lock
 vlc_playlist_Unlock
 vlc_playlist_AddListener
diff --git a/src/playlist/playlist.c b/src/playlist/playlist.c
index 4a1c3b38e1..bea773385e 100644
--- a/src/playlist/playlist.c
+++ b/src/playlist/playlist.c
@@ -62,10 +62,12 @@ vlc_playlist_New(vlc_object_t *parent)
     playlist->auto_preparse = var_InheritBool(parent, "auto-preparse");
 #endif
 
+    vlc_atomic_rc_init(&playlist->rc);
+
     return playlist;
 }
 
-void
+static void
 vlc_playlist_Delete(vlc_playlist_t *playlist)
 {
     assert(vlc_list_is_empty(&playlist->listeners));
@@ -76,6 +78,17 @@ vlc_playlist_Delete(vlc_playlist_t *playlist)
     free(playlist);
 }
 
+void vlc_playlist_Hold(vlc_playlist_t *playlist)
+{
+    vlc_atomic_rc_inc(&playlist->rc);
+}
+
+void vlc_playlist_Release(vlc_playlist_t *playlist)
+{
+    if (vlc_atomic_rc_dec(&playlist->rc))
+        vlc_playlist_Delete(playlist);
+}
+
 void
 vlc_playlist_Lock(vlc_playlist_t *playlist)
 {
diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h
index 2a696c6cb0..7fd34a10c5 100644
--- a/src/playlist/playlist.h
+++ b/src/playlist/playlist.h
@@ -22,6 +22,7 @@
 #define VLC_PLAYLIST_NEW_INTERNAL_H
 
 #include <vlc_common.h>
+#include <vlc_atomic.h>
 #include <vlc_playlist.h>
 #include <vlc_vector.h>
 #include "../player/player.h"
@@ -61,6 +62,8 @@ struct vlc_playlist
     enum vlc_playlist_playback_repeat repeat;
     enum vlc_playlist_playback_order order;
     uint64_t idgen;
+
+    vlc_atomic_rc_t rc;
 };
 
 /* Also disable vlc_assert_locked in tests since the symbol is not exported */
diff --git a/src/playlist/test.c b/src/playlist/test.c
index bb9290925c..3d8c5b8aa1 100644
--- a/src/playlist/test.c
+++ b/src/playlist/test.c
@@ -106,7 +106,7 @@ test_append(void)
     EXPECT_AT(9, 9);
 
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -155,7 +155,7 @@ test_insert(void)
     EXPECT_AT(14, 4);
 
     DestroyMediaArray(media, 15);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -200,7 +200,7 @@ test_move(void)
     EXPECT_AT(9, 9);
 
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -231,7 +231,7 @@ test_remove(void)
     EXPECT_AT(4, 9);
 
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -252,7 +252,7 @@ test_clear(void)
     assert(vlc_playlist_Count(playlist) == 0);
 
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -312,7 +312,7 @@ test_expand_item(void)
 
     input_item_node_Delete(root);
     DestroyMediaArray(media, 16);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 struct playlist_state
@@ -651,7 +651,7 @@ test_items_added_callbacks(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -767,7 +767,7 @@ test_items_moved_callbacks(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -858,7 +858,7 @@ test_items_removed_callbacks(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -912,7 +912,7 @@ test_items_reset_callbacks(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -943,7 +943,7 @@ test_playback_repeat_changed_callbacks(void)
 
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -974,7 +974,7 @@ test_playback_order_changed_callbacks(void)
 
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1033,7 +1033,7 @@ test_callbacks_on_add_listener(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1062,7 +1062,7 @@ test_index_of(void)
     vlc_playlist_item_Release(item);
 
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1138,7 +1138,7 @@ test_prev(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 4);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1214,7 +1214,7 @@ test_next(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 3);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1330,7 +1330,7 @@ test_goto(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1375,7 +1375,7 @@ test_request_insert(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 5);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1427,7 +1427,7 @@ test_request_remove_with_matching_hint(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1479,7 +1479,7 @@ test_request_remove_without_hint(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1551,7 +1551,7 @@ test_request_remove_adapt(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 11);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1607,7 +1607,7 @@ test_request_move_with_matching_hint(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1678,7 +1678,7 @@ test_request_move_without_hint(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1779,7 +1779,7 @@ test_request_move_adapt(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 16);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1880,7 +1880,7 @@ test_request_move_to_end_adapt(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 16);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1927,7 +1927,7 @@ test_request_goto_with_matching_hint(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -1974,7 +1974,7 @@ test_request_goto_without_hint(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -2021,7 +2021,7 @@ test_request_goto_adapt(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 /* this only tests that the randomizer is correctly managed by the playlist,
@@ -2162,7 +2162,7 @@ test_random(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 6);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -2242,7 +2242,7 @@ test_shuffle(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 static void
@@ -2346,7 +2346,7 @@ test_sort(void)
     callback_ctx_destroy(&ctx);
     vlc_playlist_RemoveListener(playlist, listener);
     DestroyMediaArray(media, 10);
-    vlc_playlist_Delete(playlist);
+    vlc_playlist_Release(playlist);
 }
 
 #undef EXPECT_AT
-- 
2.28.0



More information about the vlc-devel mailing list