Add sending wakeup wakeup signal to resourced 58/188858/5
authorSangyoon Jang <jeremy.jang@samsung.com>
Tue, 11 Sep 2018 03:09:48 +0000 (12:09 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Thu, 13 Sep 2018 02:00:59 +0000 (11:00 +0900)
When some process get freezed with holding pkgmgr db lock,
installer cannot install package properly.

Change-Id: I21785093cfdf065fab8f13c150e4228f3ee0ecec
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
packaging/pkgmgr-info.spec
parser/CMakeLists.txt
parser/src/pkgmgr_parser_db.c

index 9511325..8a9aa79 100644 (file)
@@ -8,6 +8,8 @@ Source0:    %{name}-%{version}.tar.gz
 Source1001: pkgmgr-info.manifest
 BuildRequires: cmake
 BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gio-2.0)
 BuildRequires: pkgconfig(vconf)
 BuildRequires: pkgconfig(sqlite3)
 BuildRequires: pkgconfig(db-util)
index 10bb4ff..5b203b5 100644 (file)
@@ -33,7 +33,7 @@ endif()
 ### Get required CFLAGS, LDFLAGS from pkg-config
 
 include(FindPkgConfig)
-pkg_check_modules(parser_pkgs REQUIRED dlog libxml-2.0 glib-2.0 sqlite3 db-util vconf bundle capi-system-info libsmack)
+pkg_check_modules(parser_pkgs REQUIRED dlog libxml-2.0 glib-2.0 gio-2.0 sqlite3 db-util vconf bundle capi-system-info libsmack)
 
 foreach(flag ${parser_pkgs_CFLAGS})
        set(parser_pkgs_CFLAGS_str "${parser_pkgs_CFLAGS_str} ${flag}")
index 93d2e1a..8745594 100644 (file)
@@ -27,6 +27,7 @@
 #include <pwd.h>
 
 #include <glib.h>
+#include <gio/gio.h>
 #include <sqlite3.h>
 
 #include <tzplatform_config.h>
@@ -460,6 +461,50 @@ API int pkgmgr_parser_create_and_initialize_db(uid_t uid)
        return PM_PARSER_R_OK;
 }
 
+#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"
+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;
@@ -506,21 +551,28 @@ static void __check_db_lock(const char *dbpath)
                }
 
                _LOGE("%s (%d) has lock on pkgmgr db(%s)!", name, pid, dbpath);
+               __send_wakeup_signal_to_resourced(pid);
        }
 
        fclose(fp);
 }
 
 #define BUSY_WAITING_USEC (1000000 / 10 / 2) /* 0.05 sec */
-#define BUSY_WAITING_MAX 20 /* wait for max 1 sec */
+#define BUSY_WAITING_MAX 40 /* wait for max 2 sec */
 static int __db_busy_handler(void *data, int count)
 {
-       if (count < BUSY_WAITING_MAX) {
+       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 */
-               __check_db_lock((const char *)data);
                return 0;
        }
 }