From 52a9e4087f38c285d9e83a6647b6c13daedbdb7d Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 15 Feb 2017 13:56:01 +0900 Subject: [PATCH] Add db busy handler 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 --- src/pkgmgrinfo_appinfo.c | 4 ++-- src/pkgmgrinfo_certinfo.c | 10 +++++----- src/pkgmgrinfo_pkginfo.c | 2 +- src/pkgmgrinfo_private.c | 31 +++++++++++++++++++++++++++++++ src/pkgmgrinfo_private.h | 1 + 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/pkgmgrinfo_appinfo.c b/src/pkgmgrinfo_appinfo.c index 92c8647..6d9bc49 100644 --- a/src/pkgmgrinfo_appinfo.c +++ b/src/pkgmgrinfo_appinfo.c @@ -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; diff --git a/src/pkgmgrinfo_certinfo.c b/src/pkgmgrinfo_certinfo.c index 48ca571..0e5f24a 100644 --- a/src/pkgmgrinfo_certinfo.c +++ b/src/pkgmgrinfo_certinfo.c @@ -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); diff --git a/src/pkgmgrinfo_pkginfo.c b/src/pkgmgrinfo_pkginfo.c index 5c0792c..f838d35 100644 --- a/src/pkgmgrinfo_pkginfo.c +++ b/src/pkgmgrinfo_pkginfo.c @@ -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); diff --git a/src/pkgmgrinfo_private.c b/src/pkgmgrinfo_private.c index 1d31430..d2584a1 100644 --- a/src/pkgmgrinfo_private.c +++ b/src/pkgmgrinfo_private.c @@ -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; +} diff --git a/src/pkgmgrinfo_private.h b/src/pkgmgrinfo_private.h index f78c5cb..c0822be 100644 --- a/src/pkgmgrinfo_private.h +++ b/src/pkgmgrinfo_private.h @@ -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 -- 2.7.4