#define RESOURCED_PROC_PATH "/Org/Tizen/ResourceD/Process"
#define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process"
#define RESOURCED_PROC_METHOD "ProcExclude"
+// This should be removed when the client server structure is complete
static void __send_wakeup_signal_to_resourced(pid_t pid)
{
GError *error = NULL;
g_object_unref(conn);
}
+// This should be removed when the client server structure is complete
static void __check_db_lock(const char *dbpath)
{
FILE *fp;
#define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
#define BUSY_WAITING_MAX 100 /* wait for max 5 sec */
+
+// This should be removed when the client server structure is complete
static int __db_busy_handler(void *data, int count)
{
if (count < (BUSY_WAITING_MAX / 2)) {
return 0;
}
-static int __open_db(uid_t uid, const char *path, sqlite3 **db, int flags)
-{
- int ret;
-
- ret = sqlite3_open_v2(path, db, flags, NULL);
- if (ret != SQLITE_OK) {
- sqlite3_close_v2(*db);
- return ret;
- }
-
- ret = sqlite3_busy_handler(*db, __db_busy_handler, (void *)path);
- if (ret != SQLITE_OK) {
- _LOGE("failed to register busy handler: %s",
- sqlite3_errmsg(*db));
- sqlite3_close_v2(*db);
- return ret;
- }
-
- ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL);
- if (ret != SQLITE_OK) {
- _LOGE("failed to enable foreign key support: %s",
- sqlite3_errmsg(*db));
- sqlite3_close_v2(*db);
- return ret;
- }
-
- return ret;
-}
-
static int __delete_package_info(sqlite3 *db, const char *pkgid)
{
static const char query[] =
dbpath = __get_parser_db_path(uid);
- ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
+ //ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
+ ret = 0;
if (ret != SQLITE_OK) {
_LOGE("open db failed: %d", ret);
return PM_PARSER_R_ERROR;
dbpath = __get_parser_db_path(uid);
- ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
+ //ret = __open_db(uid, dbpath, &db, SQLITE_OPEN_READWRITE);
+ ret = 0;
if (ret != SQLITE_OK) {
_LOGE("open db failed: %d", ret);
return PM_PARSER_R_ERROR;
#include "abstract_db_handler.hh"
+#include <gio/gio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
#include <stdlib.h>
#include <tzplatform_config.h>
#include <string>
#include "pkgmgr-info.h"
+#include "pkgmgrinfo_debug.h"
#include "pkgmgrinfo_private.h"
namespace {
return uid;
}
+#define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
+#define BUSY_WAITING_MAX 100 /* wait for max 5 sec */
+
+static int __readdb_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_read_db(const char *path, sqlite3 **db, int flags) {
+ int ret;
+
+ ret = sqlite3_open_v2(path, db, flags, NULL);
+ if (ret != SQLITE_OK) {
+ sqlite3_close_v2(*db);
+ return ret;
+ }
+
+ ret = sqlite3_busy_handler(*db, __readdb_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;
+}
+
+#define RESOURCED_BUS_NAME "org.tizen.resourced"
+#define RESOURCED_PROC_PATH "/Org/Tizen/ResourceD/Process"
+#define RESOURCED_PROC_INTERFACE "org.tizen.resourced.process"
+#define RESOURCED_PROC_METHOD "ProcExclude"
+// This should be removed when the client server structure is complete
+static void __send_wakeup_signal_to_resourced(pid_t pid) {
+ GError *error = NULL;
+ GDBusConnection *conn;
+ GDBusProxy *proxy;
+ GVariant *reply;
+
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (conn == NULL) {
+ _LOGE("Failed to connect to dbus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ proxy = g_dbus_proxy_new_sync(conn,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ NULL, RESOURCED_BUS_NAME,
+ RESOURCED_PROC_PATH, RESOURCED_PROC_INTERFACE,
+ NULL, &error);
+ if (proxy == NULL) {
+ _LOGE("failed to get proxy object: %s", error->message);
+ g_error_free(error);
+ g_object_unref(conn);
+ return;
+ }
+
+ reply = g_dbus_proxy_call_sync(proxy, RESOURCED_PROC_METHOD,
+ g_variant_new("(si)", "wakeup", pid),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+ if (reply == NULL)
+ _LOGE("failed to get reply from resourced");
+ if (error) {
+ _LOGE("failed to send request: %s", error->message);
+ g_error_free(error);
+ }
+
+ g_object_unref(proxy);
+ g_object_unref(conn);
+}
+
+static void __check_db_lock(const char *dbpath) {
+ FILE *fp;
+ FILE *fp_cmdline;
+ struct stat sb;
+ char type[BUFSIZE];
+ int pid;
+ unsigned int maj;
+ unsigned int min;
+ unsigned long long ino;
+ char cmdline[BUFSIZE];
+ char name[BUFSIZE];
+ size_t len;
+
+ if (stat(dbpath, &sb) == -1) {
+ _LOGE("get db file(%s) status failed: %d", dbpath, errno);
+ return;
+ }
+
+ fp = fopen("/proc/locks", "r");
+ if (fp == NULL) {
+ _LOGE("Failed to open lock info: %d", errno);
+ return;
+ }
+
+ while (fscanf(fp, "%*s %*s %*s %5s %d %x:%x:%llu %*s %*s",
+ type, &pid, &maj, &min, &ino) != EOF) {
+ if (maj != major(sb.st_dev) || min != minor(sb.st_dev) ||
+ ino != sb.st_ino || pid == getpid() ||
+ strcasecmp(type, "WRITE"))
+ continue;
+
+ snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
+ fp_cmdline = fopen(cmdline, "r");
+ name[0] = '\0';
+ if (fp_cmdline != NULL) {
+ len = fread(name, sizeof(char), sizeof(name) - 1,
+ fp_cmdline);
+ if (len > 0) {
+ if (name[len - 1] == '\n')
+ name[len - 1] = '\0';
+ else
+ name[len] = '\0';
+ }
+ fclose(fp_cmdline);
+ }
+
+ _LOGE("%s (%d) has lock on pkgmgr db(%s)!", name, pid, dbpath);
+ __send_wakeup_signal_to_resourced(pid);
+ }
+
+ fclose(fp);
+}
+
+static int __writedb_busy_handler(void *data, int count) {
+ if (count < (BUSY_WAITING_MAX / 2)) {
+ usleep(BUSY_WAITING_USEC);
+ return 1;
+ } else if (count == (BUSY_WAITING_MAX / 2)) {
+ __check_db_lock((const char *)data);
+ usleep(BUSY_WAITING_USEC);
+ return 1;
+ } else if (count < BUSY_WAITING_MAX) {
+ usleep(BUSY_WAITING_USEC);
+ return 1;
+ } else {
+ /* sqlite3_prepare_v2 will return SQLITE_BUSY */
+ return 0;
+ }
+}
+
+static int __open_write_db(uid_t uid, const char *path, sqlite3 **db, int flags) {
+ int ret;
+
+ ret = sqlite3_open_v2(path, db, flags, NULL);
+ if (ret != SQLITE_OK) {
+ sqlite3_close_v2(*db);
+ return ret;
+ }
+
+ ret = sqlite3_busy_handler(*db, __writedb_busy_handler, (void *)path);
+ if (ret != SQLITE_OK) {
+ _LOGE("failed to register busy handler: %s",
+ sqlite3_errmsg(*db));
+ sqlite3_close_v2(*db);
+ return ret;
+ }
+
+ ret = sqlite3_exec(*db, "PRAGMA foreign_keys=ON", NULL, NULL, NULL);
+ if (ret != SQLITE_OK) {
+ _LOGE("failed to enable foreign key support: %s",
+ sqlite3_errmsg(*db));
+ sqlite3_close_v2(*db);
+ return ret;
+ }
+
+ return ret;
+}
+
} // namespace
namespace pkgmgr_common {
}
std::string db_path = GetDBPath();
int flag = 0;
+ int ret = 0;
if (op_type_ == OPERATION_TYPE_READ)
- flag = SQLITE_OPEN_READONLY;
+ ret = __open_read_db(db_path.c_str(), &db_, SQLITE_OPEN_READONLY);
else
- flag = SQLITE_OPEN_READWRITE;
+ ret = __open_write_db(uid_, db_path.c_str(), &db_,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
- int ret = __open_db(db_path.c_str(), &db_, flag);
if (ret != SQLITE_OK) {
// error log
return false;