[vlc-commits] player: make the lock optionally reentrant
Romain Vimont
git at videolan.org
Wed May 22 22:04:26 CEST 2019
vlc | branch: master | Romain Vimont <rom1v at videolabs.io> | Mon May 13 14:39:35 2019 +0200| [cff059cc20213fc6ce892202ab82f229e857c457] | committer: Jean-Baptiste Kempf
player: make the lock optionally reentrant
This will allow to implement the old libvlc API using the new player.
<https://mailman.videolan.org/pipermail/vlc-devel/2019-May/124461.html>
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=cff059cc20213fc6ce892202ab82f229e857c457
---
include/vlc_player.h | 25 ++++++++++++++++++++++++-
src/input/player.c | 12 ++++++++----
src/playlist/player.c | 3 ++-
src/playlist/playlist.h | 3 ++-
test/src/input/player.c | 6 ++++--
5 files changed, 40 insertions(+), 9 deletions(-)
diff --git a/include/vlc_player.h b/include/vlc_player.h
index 1aa5f8e687..d4c49fa89d 100644
--- a/include/vlc_player.h
+++ b/include/vlc_player.h
@@ -331,6 +331,29 @@ enum vlc_player_subtitle_sync
VLC_PLAYER_SUBTITLE_SYNC_APPLY,
};
+/**
+ * Player lock type (normal or reentrant)
+ */
+enum vlc_player_lock_type
+{
+ /**
+ * Normal lock
+ *
+ * If the player is already locked, subsequent calls to vlc_player_Lock()
+ * will deadlock.
+ */
+ VLC_PLAYER_LOCK_NORMAL,
+
+ /**
+ * Reentrant lock
+ *
+ * If the player is already locked, subsequent calls to vlc_player_Lock()
+ * will still succeed. To unlock the player, one call to
+ * vlc_player_Unlock() per vlc_player_Lock() is necessary.
+ */
+ VLC_PLAYER_LOCK_REENTRANT,
+};
+
/** Player capability: can seek */
#define VLC_PLAYER_CAP_SEEK (1<<0)
/** Player capability: can pause */
@@ -1005,7 +1028,7 @@ vlc_player_title_list_GetAt(vlc_player_title_list *titles, size_t idx);
* @return a pointer to a valid player instance or NULL in case of error
*/
VLC_API vlc_player_t *
-vlc_player_New(vlc_object_t *parent,
+vlc_player_New(vlc_object_t *parent, enum vlc_player_lock_type lock_type,
const struct vlc_player_media_provider *media_provider,
void *media_provider_data);
diff --git a/src/input/player.c b/src/input/player.c
index da02375a66..e01701ba65 100644
--- a/src/input/player.c
+++ b/src/input/player.c
@@ -3367,9 +3367,13 @@ vlc_player_vout_Snapshot(vlc_player_t *player)
}
static void
-vlc_player_InitLocks(vlc_player_t *player)
+vlc_player_InitLocks(vlc_player_t *player, enum vlc_player_lock_type lock_type)
{
- vlc_mutex_init(&player->lock);
+ if (lock_type == VLC_PLAYER_LOCK_REENTRANT)
+ vlc_mutex_init_recursive(&player->lock);
+ else
+ vlc_mutex_init(&player->lock);
+
vlc_mutex_init(&player->vout_listeners_lock);
vlc_mutex_init(&player->aout_listeners_lock);
vlc_cond_init(&player->start_delay_cond);
@@ -3426,7 +3430,7 @@ vlc_player_Delete(vlc_player_t *player)
}
vlc_player_t *
-vlc_player_New(vlc_object_t *parent,
+vlc_player_New(vlc_object_t *parent, enum vlc_player_lock_type lock_type,
const struct vlc_player_media_provider *media_provider,
void *media_provider_data)
{
@@ -3514,7 +3518,7 @@ vlc_player_New(vlc_object_t *parent,
}
player->deleting = false;
- vlc_player_InitLocks(player);
+ vlc_player_InitLocks(player, lock_type);
if (vlc_clone(&player->destructor.thread, vlc_player_destructor_Thread,
player, VLC_THREAD_PRIORITY_LOW) != 0)
diff --git a/src/playlist/player.c b/src/playlist/player.c
index 6ca6ea0636..ef65011fef 100644
--- a/src/playlist/player.c
+++ b/src/playlist/player.c
@@ -134,7 +134,8 @@ static const struct vlc_player_cbs player_callbacks = {
bool
vlc_playlist_PlayerInit(vlc_playlist_t *playlist, vlc_object_t *parent)
{
- playlist->player = vlc_player_New(parent, &player_media_provider, playlist);
+ playlist->player = vlc_player_New(parent, VLC_PLAYER_LOCK_NORMAL,
+ &player_media_provider, playlist);
if (unlikely(!playlist->player))
return false;
diff --git a/src/playlist/playlist.h b/src/playlist/playlist.h
index 253b8265ec..ef476f0597 100644
--- a/src/playlist/playlist.h
+++ b/src/playlist/playlist.h
@@ -31,7 +31,8 @@ typedef struct input_item_t input_item_t;
#ifdef TEST_PLAYLIST
/* mock the player in tests */
-# define vlc_player_New(a,b,c) (VLC_UNUSED(a), VLC_UNUSED(b), malloc(1))
+# define vlc_player_New(a,b,c,d) (VLC_UNUSED(a), VLC_UNUSED(b), VLC_UNUSED(c), \
+ malloc(1))
# define vlc_player_Delete(p) free(p)
# define vlc_player_Lock(p) VLC_UNUSED(p)
# define vlc_player_Unlock(p) VLC_UNUSED(p)
diff --git a/test/src/input/player.c b/test/src/input/player.c
index 91b2bdd474..8406e4352f 100644
--- a/test/src/input/player.c
+++ b/test/src/input/player.c
@@ -1668,7 +1668,8 @@ static void
test_delete_while_playback(vlc_object_t *obj, bool start)
{
test_log("delete_while_playback (start: %d)\n", start);
- vlc_player_t *player = vlc_player_New(obj, NULL, NULL);
+ vlc_player_t *player = vlc_player_New(obj, VLC_PLAYER_LOCK_NORMAL,
+ NULL, NULL);
struct media_params params = DEFAULT_MEDIA_PARAMS(VLC_TICK_FROM_SEC(10));
input_item_t *media = create_mock_media("media1", ¶ms);
@@ -1816,7 +1817,8 @@ REPORT_LIST
ret = var_SetString(vlc->p_libvlc_int, "window", "wdummy");
assert(ret == VLC_SUCCESS);
- ctx->player = vlc_player_New(VLC_OBJECT(vlc->p_libvlc_int), &provider, ctx);
+ ctx->player = vlc_player_New(VLC_OBJECT(vlc->p_libvlc_int),
+ VLC_PLAYER_LOCK_NORMAL, &provider, ctx);
assert(ctx->player);
vlc_player_Lock(ctx->player);
More information about the vlc-commits
mailing list