Modify watchdog feature 79/211579/4
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 7 Aug 2019 02:01:21 +0000 (11:01 +0900)
committerHwanKyu Jhun <h.jhun@samsung.com>
Thu, 8 Aug 2019 23:12:38 +0000 (23:12 +0000)
When watchdog is enabled, the app process sets the timer to start
sending ping request to amd.
If ping is not sent within a specified period, amd notifies it to
resourced. And then, the app process is terminated by resourced.

Change-Id: I4817ddb10b2d86f61630dfa0dabc44ddb2db0b22
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
include/aul_key.h
include/aul_watchdog.h
src/aul_launch.c
src/aul_watchdog.c

index 85ab539..9c03e12 100644 (file)
  * @since_tizen 5.5
  */
 #define AUL_K_LAUNCH_MODE               "__AUL_LAUNCH_MODE__"
+
+/**
+ * @brief Definition for AUL: The interval
+ * @since_tizen 5.5
+ */
+#define AUL_K_INTERVAL                  "__AUL_INTERVAL__"
index 23d5294..f7e4ddc 100644 (file)
@@ -51,6 +51,27 @@ int aul_watchdog_disable(void);
  */
 int aul_watchdog_kick(void);
 
+/**
+ * @brief Starts watchdog timer.
+ *
+ * @param[in]   interval        The interval of the timer
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ *
+ * @remarks This function is only for App Framework internally.
+ */
+void aul_watchdog_start(unsigned int interval);
+
+/**
+ * @brief Stops watchdog timer.
+ *
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ *
+ * @remarks This function is only for App Framework internally.
+ */
+void aul_watchdog_stop(void);
+
 #ifdef __cplusplus
 }
 #endif
index d0839a3..471fa77 100644 (file)
@@ -37,6 +37,7 @@
 #include "key.h"
 #include "aul_watch_control_internal.h"
 #include "aul_worker.h"
+#include "aul_watchdog.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 
@@ -209,18 +210,6 @@ static void __dispatch_app_update_requested(aul_request_h req)
        __invoke_aul_handler(AUL_UPDATE_REQUESTED, req->b);
 }
 
-static void __dispatch_watchdog_ping(aul_request_h req)
-{
-       const char *start_time;
-       struct timeval tv;
-
-       gettimeofday(&tv, NULL);
-       start_time = bundle_get_val(req->b, AUL_K_STARTTIME);
-       _W("[__WATCHDOG__] Start time: %s, response time: %ld/%ld",
-                       start_time ? start_time : "Unknown",
-                       tv.tv_sec, tv.tv_usec);
-}
-
 static void __dispatch_app_term_inst(aul_request_h req)
 {
        __invoke_aul_handler(AUL_TERMINATE_INST, req->b);
@@ -241,6 +230,26 @@ static void __dispatch_app_term_bg_inst(aul_request_h req)
        __invoke_aul_handler(AUL_TERMINATE_BG_INST, req->b);
 }
 
+static void __dispatch_watchdog_enable(aul_request_h req)
+{
+       const char *interval_str;
+       unsigned int interval;
+
+       interval_str = bundle_get_val(req->b, AUL_K_INTERVAL);
+       if (!interval_str) {
+               _E("Invalid request");
+               return;
+       }
+
+       interval = strtoul(interval_str, NULL, 10);
+       aul_watchdog_start(interval);
+}
+
+static void __dispatch_watchdog_disable(aul_request_h req)
+{
+       aul_watchdog_stop();
+}
+
 static dispatcher __dispatcher[] = {
        [APP_START] = __dispatch_app_start,
        [APP_START_RES] = __dispatch_app_start,
@@ -263,13 +272,14 @@ static dispatcher __dispatcher[] = {
        [APP_SUSPEND] = __dispatch_app_suspend,
        [WIDGET_GET_CONTENT] = __dispatch_widget_get_content,
        [APP_UPDATE_REQUESTED] = __dispatch_app_update_requested,
-       [WATCHDOG_PING] = __dispatch_watchdog_ping,
        [APP_SEND_LAUNCH_REQUEST] = __dispatch_app_start,
        [APP_SEND_LAUNCH_REQUEST_SYNC] = __dispatch_app_start,
        [APP_TERM_INSTANCE_ASYNC] = __dispatch_app_term_inst,
        [APP_RESUME_INSTANCE] = __dispatch_app_resume_inst,
        [APP_PAUSE_INSTANCE] = __dispatch_app_pause_inst,
        [APP_TERM_BG_INSTANCE] = __dispatch_app_term_bg_inst,
+       [WATCHDOG_ENABLE] = __dispatch_watchdog_enable,
+       [WATCHDOG_DISABLE] = __dispatch_watchdog_disable,
 };
 
 static void __destroy_request(struct aul_request_s *req)
index cd59cb0..ad69ee8 100644 (file)
 
 typedef struct watchdog_context_s {
        bool enabled;
+       unsigned int interval;
+       guint timer;
 } watchdog_context;
 
 static watchdog_context __context;
 
 API int aul_watchdog_enable(void)
 {
-       int r;
+       int ret;
 
        if (__context.enabled) {
                _W("Watchdog is already enabled");
                return AUL_R_OK;
        }
 
-       r = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
-                       WATCHDOG_ENABLE, NULL, 0, AUL_SOCK_NONE);
-       if (r < 0) {
-               _E("Failed to send the watchdog request. ret(%d)", r);
-               return aul_error_convert(r);
+       ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
+                       WATCHDOG_ENABLE, NULL, 0, AUL_SOCK_NOREPLY);
+       if (ret < 0) {
+               _E("Failed to send the watchdog request. ret(%d)", ret);
+               return aul_error_convert(ret);
        }
 
        __context.enabled = true;
-       _D("[__WATCHDOG__] enabled, result(%d)", r);
+       _D("[__WATCHDOG__] enabled, result(%d)", ret);
        return AUL_R_OK;
 }
 
 API int aul_watchdog_disable(void)
 {
-       int r;
+       int ret;
 
        if (!__context.enabled) {
                _W("Watchdog is not enabled");
                return AUL_R_ERROR;
        }
 
-       r = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
-                       WATCHDOG_DISABLE, NULL, 0, AUL_SOCK_NONE);
-       if (r < 0) {
-               _E("Failed to send the watchdog request. ret(%d)", r);
-               return aul_error_convert(r);
+       ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
+                       WATCHDOG_DISABLE, NULL, 0, AUL_SOCK_NOREPLY);
+       if (ret < 0) {
+               _E("Failed to send the watchdog request. ret(%d)", ret);
+               return aul_error_convert(ret);
        }
 
        __context.enabled = false;
-       _D("[__WATCHDOG__] disabled, result(%d)", r);
+       _D("[__WATCHDOG__] disabled, result(%d)", ret);
        return AUL_R_OK;
 }
 
 API int aul_watchdog_kick(void)
 {
-       int r;
+       int ret;
 
        if (!__context.enabled) {
                _W("Watchdog is not enabled");
                return AUL_R_ERROR;
        }
 
-       r = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
-                       WATCHDOG_KICK, NULL, 0, AUL_SOCK_NONE);
-       if (r < 0) {
-               _E("Failed to send the watchdog request. ret(%d)", r);
-               return aul_error_convert(r);
+       ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
+                       WATCHDOG_KICK, NULL, 0, AUL_SOCK_NOREPLY);
+       if (ret < 0) {
+               _E("Failed to send the watchdog request. ret(%d)", ret);
+               return aul_error_convert(ret);
+       }
+
+       aul_watchdog_stop();
+       aul_watchdog_start(__context.interval);
+
+       _D("[__WATCHDOG__] kicked, result(%d)", ret);
+       return AUL_R_OK;
+}
+
+static int __watchdog_ping(void)
+{
+       int ret;
+
+       ret = aul_sock_send_raw(AUL_UTIL_PID, getuid(),
+                       WATCHDOG_PING, NULL, 0, AUL_SOCK_NOREPLY);
+       if (ret < 0) {
+               _E("Failed to send watchdog ping. ret(%d)", ret);
+               return aul_error_convert(ret);
        }
 
-       _D("[__WATCHDOG__] kicked, result(%d)", r);
        return AUL_R_OK;
 }
+
+static gboolean __watchdog_notify_handler(gpointer data)
+{
+       int ret;
+
+       ret = __watchdog_ping();
+       _W("[__WATCHDOG__] Ping(%d). result(%d)", getpid(), ret);
+
+       return G_SOURCE_CONTINUE;
+}
+
+void aul_watchdog_start(unsigned int interval)
+{
+       if (__context.timer) {
+               _W("Timer already exists");
+               return;
+       }
+
+       __context.enabled = true;
+       __context.interval = interval;
+       __context.timer = g_timeout_add(interval,
+                       __watchdog_notify_handler, NULL);
+
+       __watchdog_notify_handler(NULL);
+}
+
+void aul_watchdog_stop(void)
+{
+       if (!__context.timer)
+               return;
+
+       g_source_remove(__context.timer);
+       __context.timer = 0;
+}