From 22025011b06941a311322e79331e5162959c2cf2 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 4 Jun 2020 15:25:41 +0900 Subject: [PATCH] [0.6.230] Use FIFO ticket lock when use command lock - To ensure the order of access to shared resources Change-Id: I91fb99a0cf8918c9242f0fb7c04ba2bc34725871 --- packaging/libmm-player.spec | 2 +- src/include/mm_player_priv.h | 9 ++++- src/include/mm_player_utils.h | 14 +++++-- src/mm_player.c | 9 +++-- src/mm_player_utils.c | 90 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 8 deletions(-) diff --git a/packaging/libmm-player.spec b/packaging/libmm-player.spec index 91a13e1..9179855 100644 --- a/packaging/libmm-player.spec +++ b/packaging/libmm-player.spec @@ -1,6 +1,6 @@ Name: libmm-player Summary: Multimedia Framework Player Library -Version: 0.6.229 +Version: 0.6.230 Release: 0 Group: Multimedia/Libraries License: Apache-2.0 diff --git a/src/include/mm_player_priv.h b/src/include/mm_player_priv.h index 1201b39..dc3bd70 100644 --- a/src/include/mm_player_priv.h +++ b/src/include/mm_player_priv.h @@ -504,6 +504,13 @@ typedef struct { } mmplayer_adaptive_variant_info_t; typedef struct { + GCond ticket_cond; + GMutex ticket_mutex; + guint ticket_queue_head; + guint ticket_queue_tail; +} mmplayer_ticket_lock_t; + +typedef struct { int is_spherical; int is_stitched; char *stitching_software; @@ -540,7 +547,7 @@ typedef struct { int cmd; /* command lock */ - GMutex cmd_lock; + mmplayer_ticket_lock_t *cmd_lock; GMutex reconfigure_lock; GCond reconfigure_cond; diff --git a/src/include/mm_player_utils.h b/src/include/mm_player_utils.h index 88cd995..543c5b0 100644 --- a/src/include/mm_player_utils.h +++ b/src/include/mm_player_utils.h @@ -60,9 +60,11 @@ #define MMPLAYER_GET_ATTRS(x_player) ((mmplayer_t *)x_player)->attrs /* command */ -#define MMPLAYER_CMD_LOCK(x_player) g_mutex_lock(&((mmplayer_t *)x_player)->cmd_lock) -#define MMPLAYER_CMD_TRYLOCK(x_player) g_mutex_trylock(&((mmplayer_t *)x_player)->cmd_lock) -#define MMPLAYER_CMD_UNLOCK(x_player) g_mutex_unlock(&((mmplayer_t *)x_player)->cmd_lock) +#define MMPLAYER_CMD_LOCK_INIT(x_player) _mmplayer_cmd_lock_init((mmplayer_t *)x_player) +#define MMPLAYER_CMD_LOCK(x_player) _mmplayer_cmd_lock((mmplayer_t *)x_player) +#define MMPLAYER_CMD_TRYLOCK(x_player) _mmplayer_cmd_trylock((mmplayer_t *)x_player) +#define MMPLAYER_CMD_UNLOCK(x_player) _mmplayer_cmd_unlock((mmplayer_t *)x_player) +#define MMPLAYER_CMD_LOCK_DEINIT(x_player) _mmplayer_cmd_lock_deinit((mmplayer_t *)x_player) /* pipeline reconfigure */ #define MMPLAYER_RECONFIGURE_LOCK(x_player) g_mutex_lock(&((mmplayer_t *)x_player)->reconfigure_lock) @@ -323,6 +325,12 @@ const char *_mmplayer_get_charset(const char *file_path); int _mmplayer_get_pixtype(unsigned int fourcc); bool _mmplayer_get_storage_info(const char *path, mmplayer_storage_info_t *storage_info); +/* for command lock */ +void _mmplayer_cmd_lock_init(mmplayer_t *player); +void _mmplayer_cmd_lock_deinit(mmplayer_t *player); +void _mmplayer_cmd_lock(mmplayer_t *player); +gboolean _mmplayer_cmd_trylock(mmplayer_t *player); +void _mmplayer_cmd_unlock(mmplayer_t *player); media_format_mimetype_e _mmplayer_convert_audio_pcm_str_to_media_format_mime(const gchar *audio_pcm_str); #ifdef __cplusplus diff --git a/src/mm_player.c b/src/mm_player.c index 52feafe..56d3fae 100644 --- a/src/mm_player.c +++ b/src/mm_player.c @@ -54,7 +54,7 @@ int mm_player_create(MMHandleType *player) } /* create player lock and cond */ - g_mutex_init(&new_player->cmd_lock); + MMPLAYER_CMD_LOCK_INIT(new_player); g_mutex_init(&new_player->reconfigure_lock); g_cond_init(&new_player->reconfigure_cond); @@ -86,7 +86,7 @@ ERROR: if (new_player) { _mmplayer_destroy((MMHandleType)new_player); - g_mutex_clear(&new_player->cmd_lock); + MMPLAYER_CMD_LOCK_DEINIT(new_player); g_mutex_clear(&new_player->reconfigure_lock); g_cond_clear(&new_player->reconfigure_cond); MMPLAYER_FREEIF(new_player); @@ -113,7 +113,10 @@ int mm_player_destroy(MMHandleType player) MMPLAYER_CMD_UNLOCK(player); - g_mutex_clear(&((mmplayer_t *)player)->cmd_lock); + MMPLAYER_CMD_LOCK(player); + MMPLAYER_CMD_UNLOCK(player); + + MMPLAYER_CMD_LOCK_DEINIT(player); g_mutex_clear(&((mmplayer_t *)player)->reconfigure_lock); g_cond_clear(&((mmplayer_t *)player)->reconfigure_cond); diff --git a/src/mm_player_utils.c b/src/mm_player_utils.c index 60a258e..0620af0 100644 --- a/src/mm_player_utils.c +++ b/src/mm_player_utils.c @@ -37,6 +37,7 @@ #define MEDIA_PATH_EXTERNAL tzplatform_getenv(TZ_SYS_STORAGE) /* external storage, sd card, usb */ #define FD_NUM_FOR_DEBUG 10 +#define CMD_LOCK_TICKET_MAX (G_MAXUINT - 1) const gchar * _mmplayer_get_stream_type_name(int type) @@ -658,3 +659,92 @@ gboolean _mmplayer_use_decodebin(mmplayer_t *player) /* MMPLAYER_USE_DECODEBIN(p return FALSE; } + +void _mmplayer_cmd_lock_init(mmplayer_t *player) +{ + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player); + player->cmd_lock = g_new0(mmplayer_ticket_lock_t, 1); + g_mutex_init(&player->cmd_lock->ticket_mutex); + g_cond_init(&player->cmd_lock->ticket_cond); + player->cmd_lock->ticket_queue_head = 0; + player->cmd_lock->ticket_queue_tail = 0; + MMPLAYER_FLEAVE(); +} + +void _mmplayer_cmd_lock_deinit(mmplayer_t *player) +{ + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player && player->cmd_lock); + g_mutex_clear(&player->cmd_lock->ticket_mutex); + g_cond_clear(&player->cmd_lock->ticket_cond); + player->cmd_lock->ticket_queue_head = 0; + player->cmd_lock->ticket_queue_tail = 0; + g_free(player->cmd_lock); + MMPLAYER_FLEAVE(); +} + +void _mmplayer_cmd_lock(mmplayer_t *player) +{ + guint64 queue_me; + GCond *cond; + GMutex *mutex; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player && player->cmd_lock); + + cond = &player->cmd_lock->ticket_cond; + mutex = &player->cmd_lock->ticket_mutex; + g_mutex_lock(mutex); + queue_me = player->cmd_lock->ticket_queue_tail; + player->cmd_lock->ticket_queue_tail = (queue_me + 1) % CMD_LOCK_TICKET_MAX; + while (queue_me != player->cmd_lock->ticket_queue_head) + g_cond_wait(cond, mutex); + g_mutex_unlock(mutex); + MMPLAYER_FLEAVE(); +} + +gboolean _mmplayer_cmd_trylock(mmplayer_t *player) +{ + GMutex *mutex; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_VAL_IF_FAIL(player && player->cmd_lock, FALSE); + + mutex = &player->cmd_lock->ticket_mutex; + + if (!g_mutex_trylock(mutex)) { + MMPLAYER_FLEAVE(); + return FALSE; + } + + if (player->cmd_lock->ticket_queue_tail != player->cmd_lock->ticket_queue_head) { + g_mutex_unlock(mutex); + MMPLAYER_FLEAVE(); + return FALSE; + } + g_mutex_unlock(mutex); + + _mmplayer_cmd_lock(player); + MMPLAYER_FLEAVE(); + return TRUE; +} + +void _mmplayer_cmd_unlock(mmplayer_t *player) +{ + GCond *cond; + GMutex *mutex; + + MMPLAYER_FENTER(); + MMPLAYER_RETURN_IF_FAIL(player && player->cmd_lock); + + cond = &player->cmd_lock->ticket_cond; + mutex = &player->cmd_lock->ticket_mutex; + + g_mutex_lock(mutex); + player->cmd_lock->ticket_queue_head = + (player->cmd_lock->ticket_queue_head + 1) % CMD_LOCK_TICKET_MAX; + g_cond_broadcast(cond); + g_mutex_unlock(mutex); + MMPLAYER_FLEAVE(); +} -- 2.7.4