Reduce DB locking time 99/245199/15 accepted/tizen_6.0_unified_hotfix tizen_6.0_hotfix accepted/tizen/6.0/unified/20201030.122552 accepted/tizen/6.0/unified/hotfix/20201103.004858 accepted/tizen/6.0/unified/hotfix/20201103.052243 accepted/tizen/unified/20201009.090838 submit/tizen/20201008.053624 submit/tizen_6.0/20201029.205102 submit/tizen_6.0_hotfix/20201102.192502 submit/tizen_6.0_hotfix/20201103.114802 tizen_6.0.m2_release
authorhj kim <backto.kim@samsung.com>
Mon, 5 Oct 2020 09:08:56 +0000 (18:08 +0900)
committerhj kim <backto.kim@samsung.com>
Thu, 8 Oct 2020 03:37:13 +0000 (12:37 +0900)
foreach functions invoke callback while reading DB. It means that the DB is locked.
But sometimes applications do unexpected things in callback and it could cause a long DB lock and
prevent other apps from accessing the DB.
Therefore, saving items to the internal list and unlock the DB quickly.

Change-Id: Ideb57e53a77fa3ace74cec512ca4f3adcf149549

include/media_controller_private.h
packaging/capi-media-controller.spec
src/media_controller_db.c
src/media_controller_playlist.c

index 63c6261..ac76cc4 100644 (file)
@@ -419,6 +419,11 @@ typedef struct {
        GList *item_list;
 } mc_playlist_s;
 
+typedef struct {
+       char *index;
+       media_controller_metadata_s *metadata;
+} mc_playlist_item_s;
+
 /* formal callback to receive signal */
 typedef void(*mc_signal_received_cb)(const char *interface_name, const char *signal_name, const char *message, const char *request_id, void *user_data);
 
index 46d1060..43fd00b 100644 (file)
@@ -1,6 +1,6 @@
 Name:       capi-media-controller
 Summary:    A media controller library in Tizen Native API
-Version:    0.2.21
+Version:    0.2.22
 Release:    1
 Group:      Multimedia/API
 License:    Apache-2.0
index 8fc20fa..e2d90c6 100644 (file)
@@ -88,6 +88,21 @@ static int __mc_db_get_bool_value(sqlite3 *handle, const char *server_name, cons
        return ret;
 }
 
+static void __mc_db_playlist_destroy(gpointer data)
+{
+       mc_playlist_destroy((mc_playlist_h)data);
+}
+
+static void __mc_db_playlist_item_destroy(gpointer data)
+{
+       mc_playlist_item_s *item = (mc_playlist_item_s *)data;
+       mc_retm_if_failed(item);
+
+       g_free(item->index);
+       mc_metadata_destroy((mc_metadata_h)item->metadata);
+       g_free(item);
+}
+
 int _mc_db_update_playback_info(const char *server_name, const media_controller_playback_s playback)
 {
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
@@ -493,6 +508,8 @@ int _mc_db_get_foreach_playlist(sqlite3 *handle, const char *server_name, mc_pla
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        char *sql_str = NULL;
        sqlite3_stmt *stmt = NULL;
+       GList *playlists = NULL;
+       GList *node = NULL;
 
        mc_retvm_if(!handle, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid handle");
        mc_retvm_if(!server_name, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid server_name");
@@ -511,15 +528,21 @@ int _mc_db_get_foreach_playlist(sqlite3 *handle, const char *server_name, mc_pla
                _playlist->server_name = g_strdup(server_name);
                _playlist->playlist_name = g_strdup((const char *)sqlite3_column_text(stmt, 0));
 
-               if (callback((mc_playlist_h)_playlist, user_data) == false) {
-                       mc_playlist_destroy((mc_playlist_h)_playlist);
+               playlists = g_list_append(playlists, _playlist);
+       }
+
+       SQLITE3_FINALIZE(stmt);
+
+       node = playlists;
+
+       while (node) {
+               if (!callback(node->data, user_data))
                        break;
-               }
 
-               mc_playlist_destroy((mc_playlist_h)_playlist);
+               node = g_list_next(node);
        }
 
-       SQLITE3_FINALIZE(stmt);
+       g_list_free_full(playlists, __mc_db_playlist_destroy);
 
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
@@ -597,8 +620,9 @@ int _mc_db_get_playlist_item(sqlite3 *handle, const char *server_name, char *pla
        int ret = MEDIA_CONTROLLER_ERROR_NONE;
        char *sql_str = NULL;
        sqlite3_stmt *stmt = NULL;
-       char *index = NULL;
-       mc_metadata_h _metadata = NULL;
+       mc_playlist_item_s *item = NULL;
+       GList *item_list = NULL;
+       unsigned int idx = 0, length = 0;
 
        mc_retvm_if(!handle, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid handle");
        mc_retvm_if(!server_name, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid server_name");
@@ -613,27 +637,32 @@ int _mc_db_get_playlist_item(sqlite3 *handle, const char *server_name, char *pla
        mc_retvm_if(SQLITE_OK != ret, MEDIA_CONTROLLER_ERROR_INVALID_OPERATION, "prepare error [%s]", sqlite3_errmsg(handle));
 
        while (sqlite3_step(stmt) == SQLITE_ROW) {
-               ret = __mc_db_get_metadata(stmt, 1, &_metadata);
+               item = g_new0(mc_playlist_item_s, 1);
+
+               ret = __mc_db_get_metadata(stmt, 1, (mc_metadata_h *)&item->metadata);
                if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
                        mc_error("fail to __mc_db_get_metadata");
                        SQLITE3_FINALIZE(stmt);
+                       g_list_free_full(item_list, __mc_db_playlist_item_destroy);
                        return ret;
                }
 
-               index = g_strdup((char *)sqlite3_column_text(stmt, 0));
-
-               if (callback(index, (mc_metadata_h)_metadata, user_data) == false) {
-                       g_free(index);
-                       mc_metadata_destroy((mc_metadata_h)_metadata);
-                       break;
-               }
+               item->index = g_strdup((char *)sqlite3_column_text(stmt, 0));
 
-               g_free(index);
-               mc_metadata_destroy(_metadata);
+               item_list = g_list_append(item_list, item);
        }
 
        SQLITE3_FINALIZE(stmt);
 
+       length = g_list_length(item_list);
+       for (idx = 0; idx < length; idx++) {
+               item = g_list_nth_data(item_list, idx);
+               if (callback(item->index, (mc_metadata_h)item->metadata, user_data) == false)
+                       break;
+       }
+
+       g_list_free_full(item_list, __mc_db_playlist_item_destroy);
+
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
@@ -749,6 +778,8 @@ int _mc_db_foreach_server_list(sqlite3 *handle, mc_activated_server_cb callback,
        char *sql_str = NULL;
        sqlite3_stmt *stmt = NULL;
        int idx = 0;
+       GList *list = NULL;
+       GList *node = NULL;
 
        mc_retvm_if(!handle, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid handle");
 
@@ -773,14 +804,8 @@ int _mc_db_foreach_server_list(sqlite3 *handle, mc_activated_server_cb callback,
                idx++;
                mc_info("[%d] %s", idx, server_name);
 
-               if (callback != NULL) {
-                       if (callback(server_name, user_data) == false) {
-                               g_free(server_name);
-                               break;
-                       }
-               }
-
-               g_free(server_name);
+               if (callback)
+                       list = g_list_append(list, server_name);
 
                ret = sqlite3_step(stmt);
        }
@@ -789,6 +814,19 @@ int _mc_db_foreach_server_list(sqlite3 *handle, mc_activated_server_cb callback,
 
        SQLITE3_FINALIZE(stmt);
 
+       if (callback) {
+               node = list;
+
+               while (node) {
+                       if (!callback(node->data, user_data))
+                               break;
+
+                       node = g_list_next(node);
+               }
+
+               g_list_free_full(list, g_free);
+       }
+
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
@@ -798,6 +836,8 @@ int _mc_db_foreach_client_list(sqlite3 *handle, mc_activated_client_cb callback,
        char *sql_str = NULL;
        sqlite3_stmt *stmt = NULL;
        int idx = 0;
+       GList *list = NULL;
+       GList *node = NULL;
 
        mc_retvm_if(!handle, MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER, "Invalid handle");
 
@@ -822,13 +862,8 @@ int _mc_db_foreach_client_list(sqlite3 *handle, mc_activated_client_cb callback,
                idx++;
                mc_info("[%d] %s", idx, client_name);
 
-               if (callback != NULL) {
-                       if (callback(client_name, user_data) == false) {
-                               g_free(client_name);
-                               break;
-                       }
-               }
-               g_free(client_name);
+               if (callback)
+                       list = g_list_append(list, client_name);
 
                ret = sqlite3_step(stmt);
        }
@@ -837,6 +872,19 @@ int _mc_db_foreach_client_list(sqlite3 *handle, mc_activated_client_cb callback,
 
        SQLITE3_FINALIZE(stmt);
 
+       if (callback) {
+               node = list;
+
+               while (node) {
+                       if (!callback(node->data, user_data))
+                               break;
+
+                       node = g_list_next(node);
+               }
+
+               g_list_free_full(list, g_free);
+       }
+
        return MEDIA_CONTROLLER_ERROR_NONE;
 }
 
index baefe55..7a7c129 100644 (file)
 #define MAX_PLAYLIST_LEN 100
 
 
-typedef struct {
-       char *index;
-       media_controller_metadata_s *metadata;
-} mc_playlist_item_s;
-
 static void __release_playlist_item(gpointer data)
 {
        mc_playlist_item_s *playlist_item = (mc_playlist_item_s *)data;