[0.6.216] Use FIFO ticket lock when use command lock 78/238478/1
authorGilbok Lee <gilbok.lee@samsung.com>
Thu, 4 Jun 2020 06:25:41 +0000 (15:25 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Tue, 14 Jul 2020 08:02:19 +0000 (17:02 +0900)
- To ensure the order of access to shared resources

Change-Id: I91fb99a0cf8918c9242f0fb7c04ba2bc34725871

packaging/libmm-player.spec
src/include/mm_player_priv.h
src/include/mm_player_utils.h
src/mm_player.c
src/mm_player_utils.c

index bf8cef0279e52fbc2a6549d1e5e3db0a3b859862..38da86293731da858b7e18813367d40e36ea3762 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-player
 Summary:    Multimedia Framework Player Library
-Version:    0.6.215
+Version:    0.6.216
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
index 25c944c9b616e2669feacbf4f99b868fc6eb7e4c..a5a7f3d7bd2aa453d7b306ba413a89fbb54df547 100644 (file)
@@ -499,6 +499,13 @@ typedef struct {
        stream_variant_t limit;
 } 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;
@@ -536,7 +543,7 @@ typedef struct {
        int cmd;
 
        /* command lock */
-       GMutex cmd_lock;
+       mmplayer_ticket_lock_t *cmd_lock;
        GMutex reconfigure_lock;
        GCond reconfigure_cond;
 
index 4f12889b70e6149572727e06994e4864dfa0bc64..df3cd3fb44cdb40862e70cbba71b48bbe6a98ce6 100644 (file)
 #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)
@@ -314,6 +316,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
index bcd2d7d9422fd4a671d002d28b173d939d6d46e9..20a33013a0695fff718a60b780e566286d124b16 100644 (file)
@@ -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);
@@ -112,7 +112,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);
 
index dfddc91aabf8f69870d939ad2548f460c6cf80bc..09f7eecf6cd2aa4dc0b83ac4f96557bac28ea9c0 100644 (file)
@@ -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)
@@ -643,3 +644,92 @@ media_format_mimetype_e _mmplayer_convert_audio_pcm_str_to_media_format_mime(con
                return MEDIA_FORMAT_MAX;
        }
 }
+
+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();
+}