Bind begin and finish transaction 14/238914/7
authorYunjin Lee <yunjin-.lee@samsung.com>
Mon, 20 Jul 2020 08:15:24 +0000 (17:15 +0900)
committerYunjin Lee <yunjin-.lee@samsung.com>
Thu, 23 Jul 2020 06:44:31 +0000 (06:44 +0000)
- Bind begin and finish transaction process as macros.
- Add retry for begin transaction.

Change-Id: I462356303732bafe1bbbba35581abcd2f6698427
Signed-off-by: Yunjin Lee <yunjin-.lee@samsung.com>
capi/src/privilege_db_manager.c

index 6d3cd221c67e561d1b7d0930dff2c20bd6eb3b84..764abb4ed363da55bcc6f2de119596d976e671d4 100755 (executable)
@@ -47,6 +47,9 @@
 
 #define STORAGE_PRIVACY "http://tizen.org/privacy/storage"
 
+#define MAX_RETRY_CNT 10 // max 0.5s
+#define USLEEP_TIME (50 * 1000) // 0.05s
+
 #include <iniparser.h>
 privilege_profile_type_e get_priv_profile()
 {
@@ -114,6 +117,19 @@ privilege_profile_type_e get_priv_profile()
        } \
 }
 
+#define TRY_BEGIN_TRANSACTION(db) { \
+       if (__begin_transaction(db) != PRIVILEGE_DB_MANAGER_ERR_NONE) { \
+               __finalize_db(db, NULL, NULL); \
+               return PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL; \
+       } \
+}
+
+#define TRY_FINISH_TRANSACTION(result, db, stmt, sql) { \
+       int ret_val = __finish_transaction(result, db); \
+       __finalize_db(db, stmt, sql); \
+       return ret_val; \
+}
+
 #define SAFE_FREE(var) { if ((var) != NULL) {free(var); var = NULL; } }
 #define SAFE_SQLITE_FREE(sql) { if ((sql) != NULL) {sqlite3_free(sql); sql = NULL; } }
 #define SAFE_SQLITE_FINALIZE(stmt) { if ((stmt) != NULL) {sqlite3_finalize(stmt); stmt = NULL; } }
@@ -194,6 +210,47 @@ static int __prepare_stmt(sqlite3 *db, char* sql, sqlite3_stmt **stmt)
        return PRIVILEGE_DB_MANAGER_ERR_NONE;
 }
 
+static int __finish_transaction(int result, sqlite3 *db)
+{
+       if (result != PRIVILEGE_DB_MANAGER_ERR_NONE) {
+               _LOGE("DB update failed. Try ROLLBACK TRANSACTION.");
+               if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
+                       _LOGE("[DB_FAIL] sqlite3_exec for 'ROLLBACK TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
+               }
+       } else {
+               if (sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
+                       _LOGE("[DB_FAIL] sqlite3_exec for 'COMMIT TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
+                       return PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL;
+               }
+       }
+       return result;
+}
+
+static int __begin_transaction(sqlite3 *db)
+{
+       int ret = -1;
+       int retry_cnt = 0;
+
+       while (ret != SQLITE_OK) {
+               ret = sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL);
+               if (ret != SQLITE_OK) {
+                       _LOGE("sqlite3_exec() for BEGIN IMMEDIATE TRANSACTION failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
+                       if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
+                               if (retry_cnt < MAX_RETRY_CNT) {
+                                       retry_cnt++;
+                                       usleep(USLEEP_TIME);
+                               } else {
+                                       _LOGE("Exceed MAX_RETRY_CNT. BEGIN IMMEDIATE TRANSACTION failed.");
+                                       return PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL;
+                               }
+                       } else {
+                               return PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL;
+                       }
+               }
+       }
+    return PRIVILEGE_DB_MANAGER_ERR_NONE;
+}
+
 static int __make_privilege_list_str(GList *privilege_list, char** privilege_list_str)
 {
        char* temp_privilege_list_str = NULL;
@@ -587,7 +644,6 @@ int privilege_db_manager_get_privacy_list(GList **privacy_list)
        __finalize_db(db, stmt, sql);
 
        return PRIVILEGE_DB_MANAGER_ERR_NONE;
-
 }
 
 int privilege_db_manager_get_privilege_list_by_privacy(const char* privacy, GList **privilege_list)
@@ -662,7 +718,6 @@ int privilege_db_manager_get_same_privacy_grouped_privileges(const char* privile
        *privilege_list = temp_privilege_list;
 
        return PRIVILEGE_DB_MANAGER_ERR_NONE;
-
 }
 
 int privilege_db_manager_get_privacy_id_by_privilege(const char* privilege, int *privacy_id)
@@ -716,7 +771,6 @@ int privilege_db_manager_get_privacy_id(const char* privacy, int *privacy_id)
        return ret;
 }
 
-
 int privilege_db_manager_get_black_list(privilege_manager_policy_type_e policy_type, int uid, privilege_manager_package_type_e package_type, GList **privilege_list)
 {
        sqlite3 *db = NULL;
@@ -755,7 +809,7 @@ int privilege_db_manager_set_black_list(int uid, privilege_manager_package_type_
 
        TRY_INIT_DB(PRIVILEGE_DB_TYPE_POLICY_RW, &db);
 
-       TryReturn(sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL) == SQLITE_OK, __finalize_db(db, NULL, NULL), PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL, "[DB_FAIL] sqlite3_exec for BEGIN IMMEDIATE TRANSACTION failed");
+       TRY_BEGIN_TRANSACTION(db);
 
        for (GList *l = privilege_list; l != NULL; l = l->next) {
                char *privilege_name = (char *)l->data;
@@ -775,21 +829,7 @@ int privilege_db_manager_set_black_list(int uid, privilege_manager_package_type_
                SAFE_SQLITE_FREE(sql);
        }
 
-       if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE) {
-               _LOGE("DB update failed. Try ROLLBACK TRANSACTION.");
-               if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'ROLLBACK TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-               }
-       } else {
-               if (sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'COMMIT TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-                       ret = PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL;
-               }
-       }
-
-       __finalize_db(db, stmt, sql);
-
-       return ret;
+       TRY_FINISH_TRANSACTION(ret, db, stmt, sql);
 }
 
 int privilege_db_manager_unset_black_list(int uid, privilege_manager_package_type_e package_type, GList *privilege_list)
@@ -801,7 +841,7 @@ int privilege_db_manager_unset_black_list(int uid, privilege_manager_package_typ
 
        TRY_INIT_DB(PRIVILEGE_DB_TYPE_POLICY_RW, &db);
 
-       TryReturn(sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL) == SQLITE_OK, __finalize_db(db, NULL, NULL), PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL, "[DB_FAIL] sqlite3_exec for BEGIN IMMEDIATE TRANSACTION failed");
+       TRY_BEGIN_TRANSACTION(db);
 
        for (GList *l = privilege_list; l != NULL; l = l->next) {
                char *privilege_name = (char *)l->data;
@@ -822,21 +862,7 @@ int privilege_db_manager_unset_black_list(int uid, privilege_manager_package_typ
                SAFE_SQLITE_FREE(sql);
        }
 
-       if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE) {
-               _LOGE("DB update failed. Try ROLLBACK TRANSACTION.");
-               if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'ROLLBACK TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-               }
-       } else {
-               if (sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'COMMIT TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-                       ret = PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL;
-               }
-       }
-
-       __finalize_db(db, stmt, sql);
-
-       return ret;
+       TRY_FINISH_TRANSACTION(ret, db, stmt, sql);
 }
 
 //TODO: Do insert only. DO NOT determine whether to insert or not in here.
@@ -853,7 +879,7 @@ int privilege_db_manager_set_package_critical_privilege_info(const uid_t uid, co
        ret = privilege_db_manager_get_mapped_privilege_list(api_version, package_type, critical_privilege_list, &mapped_privilege_list);
        TryReturn(ret == PRIVILEGE_DB_MANAGER_ERR_NONE && mapped_privilege_list != NULL, __finalize_db(db, stmt, NULL), PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL, "[DB_FAIL] privilege_db_manager_get_mapped_privilege_list failed");
 
-       TryReturn(sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL) == SQLITE_OK, __finalize_db(db, NULL, NULL), PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL, "[DB_FAIL] sqlite3_exec for BEGIN IMMEDIATE TRANSACTION failed");
+       TRY_BEGIN_TRANSACTION(db);
 
        for (GList *l = mapped_privilege_list; l != NULL; l = l->next) {
                char *privilege_name = (char *)l->data;
@@ -881,21 +907,8 @@ int privilege_db_manager_set_package_critical_privilege_info(const uid_t uid, co
                }
        }
        SAFE_G_LIST_FREE_FULL(mapped_privilege_list, free);
-       if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE) {
-               _LOGE("DB update failed. Try ROLLBACK TRANSACTION.");
-               if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'ROLLBACK TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-               }
-       } else {
-               if (sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'COMMIT TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-                       ret = PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL;
-               }
-       }
-
-       __finalize_db(db, stmt, sql);
 
-       return ret;
+       TRY_FINISH_TRANSACTION(ret, db, stmt, sql);
 }
 
 //TODO: Do insert only. DO NOT determine whether to insert or not in here.
@@ -913,7 +926,8 @@ int privilege_db_manager_set_package_privacy_privilege_info(const uid_t uid, con
        ret = privilege_db_manager_get_mapped_privilege_list(api_version, package_type, privilege_list, &mapped_privilege_list);
        TryReturn(ret == PRIVILEGE_DB_MANAGER_ERR_NONE && mapped_privilege_list != NULL, __finalize_db(db, stmt, NULL), PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL, "[DB_FAIL] privilege_db_manager_get_mapped_privilege_list failed");
 
-       TryReturn(sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL) == SQLITE_OK, __finalize_db(db, NULL, NULL), PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL, "[DB_FAIL] sqlite3_exec for BEGIN IMMEDIATE TRANSACTION failed");
+       TRY_BEGIN_TRANSACTION(db);
+
        GList *l = NULL;
        for (l = mapped_privilege_list; l != NULL; l = l->next) {
                char *privilege_name = (char *)l->data;
@@ -941,21 +955,8 @@ int privilege_db_manager_set_package_privacy_privilege_info(const uid_t uid, con
                }
        }
        SAFE_G_LIST_FREE_FULL(mapped_privilege_list, free);
-       if (ret != PRIVILEGE_DB_MANAGER_ERR_NONE) {
-               _LOGE("DB update failed. Try ROLLBACK TRANSACTION.");
-               if (sqlite3_exec(db, "ROLLBACK TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'ROLLBACK TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-               }
-       } else {
-               if (sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL) != SQLITE_OK) {
-                       _LOGE("[DB_FAIL] sqlite3_exec for 'COMMIT TRANSACTION' failed. ret %d[%s]", sqlite3_errcode(db), sqlite3_errmsg(db));
-                       ret = PRIVILEGE_DB_MANAGER_ERR_DB_UPDATE_FAIL;
-               }
-       }
-
-       __finalize_db(db, stmt, sql);
 
-       return ret;
+       TRY_FINISH_TRANSACTION(ret, db, stmt, sql);
 }
 
 int privilege_db_manager_unset_package_privilege_info(const uid_t uid, const char* pkgid)
@@ -1123,8 +1124,8 @@ int privilege_db_manager_get_package_list_by_privacy(const uid_t uid, const char
                return PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT;
 
        return PRIVILEGE_DB_MANAGER_ERR_NONE;
-
 }
+
 int privilege_db_manager_get_privilege_list_by_pkgid_and_privacy(const uid_t uid, const char* pkgid, const char* privacy, GList** privilege_list)
 {
        sqlite3 *db = NULL;
@@ -1149,5 +1150,4 @@ int privilege_db_manager_get_privilege_list_by_pkgid_and_privacy(const uid_t uid
                return PRIVILEGE_DB_MANAGER_ERR_NO_EXIST_RESULT;
 
        return PRIVILEGE_DB_MANAGER_ERR_NONE;
-
 }