Add db busy handler 75/114775/1
authorSangyoon Jang <s89.jang@samsung.com>
Wed, 15 Feb 2017 04:56:01 +0000 (13:56 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Wed, 15 Feb 2017 04:56:01 +0000 (13:56 +0900)
When some process is writing on db, pkgmgr-info api fails query with
SQLITE_BUSY error. To fix this issue, the busy handler will be registered
and wait for lock released max 1 sec.

Change-Id: I04992e27f549908bd778a870114e2bd7c4d4a8de
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
src/pkgmgrinfo_appinfo.c
src/pkgmgrinfo_certinfo.c
src/pkgmgrinfo_pkginfo.c
src/pkgmgrinfo_private.c
src/pkgmgrinfo_private.h

index 92c8647..6d9bc49 100644 (file)
@@ -569,7 +569,7 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
        if (dbpath == NULL)
                return PMINFO_R_ERROR;
 
-       ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
+       ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
        if (ret != SQLITE_OK) {
                _LOGE("failed to open db: %d", ret);
                free(dbpath);
@@ -1625,7 +1625,7 @@ static char *_get_localed_label(const char *appid, const char *locale, uid_t uid
                goto err;
        }
 
-       if (sqlite3_open_v2(parser_db, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) {
+       if (__open_db(parser_db, &db, SQLITE_OPEN_READONLY) != SQLITE_OK) {
                _LOGE("DB open fail\n");
                free(parser_db);
                goto err;
index 48ca571..0e5f24a 100644 (file)
@@ -129,7 +129,7 @@ API int pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(const char *lhs_package_id,
        if (dbpath == NULL)
                return PMINFO_R_ERROR;
 
-       ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
+       ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
        if (ret != SQLITE_OK) {
                _LOGE("failed to open db: %d", ret);
                free(dbpath);
@@ -168,7 +168,7 @@ static int _pkginfo_get_pkgid_from_appid(uid_t uid, const char *appid,
        if (dbpath == NULL)
                return PMINFO_R_ERROR;
 
-       ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
+       ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
        if (ret != SQLITE_OK) {
                _LOGE("failed to open db: %d", ret);
                free(dbpath);
@@ -367,7 +367,7 @@ static int _pkginfo_get_certinfo(const char *pkgid, pkgmgr_certinfo_x *info)
        if (dbpath == NULL)
                return PMINFO_R_ERROR;
 
-       ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
+       ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
        if (ret != SQLITE_OK) {
                _LOGE("failed to open db: %d", ret);
                free(dbpath);
@@ -608,7 +608,7 @@ API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h ha
        if (dbpath == NULL)
                return PMINFO_R_ERROR;
 
-       ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
+       ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE);
        if (ret != SQLITE_OK) {
                _LOGE("failed to open db: %d", ret);
                free(dbpath);
@@ -721,7 +721,7 @@ API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
        if (dbpath == NULL)
                return PMINFO_R_ERROR;
 
-       ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
+       ret = __open_db(dbpath, &db, SQLITE_OPEN_READWRITE, NULL);
        if (ret != SQLITE_OK) {
                _LOGE("failed to open db: %d", ret);
                free(dbpath);
index 5c0792c..f838d35 100644 (file)
@@ -374,7 +374,7 @@ static int _pkginfo_get_packages(uid_t uid, const char *locale,
        if (dbpath == NULL)
                return PMINFO_R_ERROR;
 
-       ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
+       ret = __open_db(dbpath, &db, SQLITE_OPEN_READONLY);
        if (ret != SQLITE_OK) {
                _LOGD("failed to open db: %d", ret);
                free(dbpath);
index 1d31430..d2584a1 100644 (file)
@@ -519,3 +519,34 @@ int __appinfo_check_installed_storage(application_x *appinfo)
        return PMINFO_R_OK;
 }
 
+#define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
+#define BUSY_WAITING_MAX 20 /* wait for max 1 sec */
+static int __db_busy_handler(void *data, int count)
+{
+       if (count < BUSY_WAITING_MAX) {
+               usleep(BUSY_WAITING_USEC);
+               return 1;
+       } else {
+               /* sqlite3_prepare_v2 will return SQLITE_BUSY */
+               return 0;
+       }
+}
+
+int __open_db(const char *path, sqlite3 **db, int flags)
+{
+       int ret;
+
+       ret = sqlite3_open_v2(path, db, flags, NULL);
+       if (ret != SQLITE_OK)
+               return ret;
+
+       ret = sqlite3_busy_handler(*db, __db_busy_handler, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("failed to register busy handler: %s",
+                               sqlite3_errmsg(*db));
+               sqlite3_close_v2(*db);
+               return ret;
+       }
+
+       return ret;
+}
index f78c5cb..c0822be 100644 (file)
@@ -246,6 +246,7 @@ int _add_icon_info_into_list(const char *locale, char *value, GList **icon);
 int _add_label_info_into_list(const char *locale, char *value, GList **label);
 int __pkginfo_check_installed_storage(package_x *pkginfo);
 int __appinfo_check_installed_storage(application_x *appinfo);
+int __open_db(const char *path, sqlite3 **db, int flags);
 
 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
 #define REGULAR_USER 5000