Add watchdog for mainloop 61/120161/7
authorJeongmo Yang <jm80.yang@samsung.com>
Wed, 22 Mar 2017 02:55:38 +0000 (11:55 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Wed, 22 Mar 2017 10:33:01 +0000 (19:33 +0900)
[Version] 0.1.61
[Profile] Common
[Issue Type] Update
[Dependency module] N/A
[Test] [M(T) - Boot=(OK), sdb=(OK), Home=(OK), Touch=(OK), Version=tizen-3.0-mobile_20170321.3]

Change-Id: I89c0015c1f25709b05cd68e20beed0baf12522b2
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
include/muse_core_private.h
packaging/mused.spec
src/muse_core.c

index e10509d..629c14f 100644 (file)
@@ -78,9 +78,12 @@ typedef struct muse_core {
        int stop;
        int retval;
        gint running;
+       GMutex watchdog_lock;
+       GCond watchdog_cond;
+       gboolean watchdog_run;
+       GThread *watchdog_thread;
 } muse_core_t;
 
-gpointer muse_core_main_loop(gpointer data);
 muse_core_t *muse_core_new(void);
 gboolean muse_core_is_log_enabled(void);
 
index 695221c..a27174e 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mused
 Summary:    A Multimedia Daemon in Tizen Native API
-Version:    0.1.60
+Version:    0.1.61
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0
index 2e81d71..8e7006f 100644 (file)
 #define MUSE_LWIPC_WAIT_TIME 1000
 #endif
 
+#define MUSE_CORE_WATCHDOG_CHECK_PERIOD 10
+#define MUSE_CORE_WATCHDOG_CHECK_COUNT  3
+#define MUSE_CORE_WATCHDOG_TIMER_PERIOD 5
+
 static GMainLoop *g_loop;
-static GThread *g_thread;
 static GMutex g_mutex;
 static GHashTable *g_table;
 static int g_table_id;
@@ -176,6 +179,10 @@ static muse_core_t *_muse_core_create_new_server_from_fd(int fd[], int type)
                }
        }
 
+       g_mutex_init(&server->watchdog_lock);
+       g_cond_init(&server->watchdog_cond);
+       server->watchdog_run = TRUE;
+
        LOGD("Leave");
        return server;
 }
@@ -188,6 +195,22 @@ static int _muse_core_free(muse_core_t *server)
 
        g_return_val_if_fail(server, retval);
 
+       /* watchdog thread exit */
+       g_mutex_lock(&server->watchdog_lock);
+       server->watchdog_run = FALSE;
+       g_cond_signal(&server->watchdog_cond);
+       g_mutex_unlock(&server->watchdog_lock);
+
+       LOGW("join watchdog thread - start");
+
+       g_thread_join(server->watchdog_thread);
+       server->watchdog_thread = NULL;
+
+       LOGW("join watchdog thread - done");
+
+       g_mutex_clear(&server->watchdog_lock);
+       g_cond_clear(&server->watchdog_cond);
+
        retval = server->retval;
        close(server->fd);
        if (server->data_fd > 0)
@@ -196,7 +219,10 @@ static int _muse_core_free(muse_core_t *server)
                remove(UDS_files[i]);
        remove(muse_core_config_get_instance()->lockfile);
        remove(MUSE_DEFAULT_PIDFILE);
-       MUSE_FREE(server);
+
+       free(server);
+       server = NULL;
+
        muse_core_workqueue_get_instance()->shutdown();
        muse_core_config_get_instance()->free();
        muse_core_module_get_instance()->free();
@@ -402,8 +428,62 @@ static gpointer _muse_core_client_get_fd_ptr(int sock_fd)
        return g_hash_table_lookup(g_table, GINT_TO_POINTER(sock_fd));
 }
 
-gpointer muse_core_main_loop(gpointer data)
+static gboolean _muse_core_main_loop_watchdog_timer(gpointer data)
 {
+       static int count = 0;
+       muse_core_t *server = (muse_core_t *)data;
+
+       if (!server) {
+               LOGE("NULL server");
+               return FALSE;
+       }
+
+       /*LOGI("watch dog timer : %p", server);*/
+
+       count++;
+
+       g_mutex_lock(&server->watchdog_lock);
+       g_cond_signal(&server->watchdog_cond);
+       g_mutex_unlock(&server->watchdog_lock);
+
+       return TRUE;
+}
+
+static gpointer _muse_core_main_loop_watchdog(gpointer data)
+{
+       muse_core_t *server = (muse_core_t *)data;
+       gint64 end_time = 0;
+       guint try_count = 0;
+
+       if (!server) {
+               LOGE("NULL server");
+               return NULL;
+       }
+
+       LOGW("watch dog start : %p", server);
+
+       g_mutex_lock(&server->watchdog_lock);
+
+       while (server->watchdog_run) {
+               end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND * MUSE_CORE_WATCHDOG_CHECK_PERIOD;
+               if (g_cond_wait_until(&server->watchdog_cond, &server->watchdog_lock, end_time)) {
+                       /*LOGI("signal received");*/
+                       try_count = 0;
+               } else {
+                       LOGW("timeout");
+                       try_count++;
+               }
+
+               if (try_count >= MUSE_CORE_WATCHDOG_CHECK_COUNT) {
+                       LOGE("NO RESPONSE FOR MAINLOOP");
+                       muse_core_respawn(SIGABRT);
+               }
+       }
+
+       g_mutex_unlock(&server->watchdog_lock);
+
+       LOGW("leave");
+
        return NULL;
 }
 
@@ -436,12 +516,13 @@ muse_core_t *muse_core_new()
 
 int muse_core_run()
 {
+       guint watchdog_timer_id = 0;
        muse_core_t *server;
 #ifndef MUSE_USE_LWIPC
        int ready_fd;
 #endif
 
-       LOGI("Enter");
+       LOGW("Enter");
 
        g_return_val_if_fail(_muse_core_run() == MM_ERROR_NONE, MUSE_ERR);
 
@@ -455,8 +536,6 @@ int muse_core_run()
        g_loop = g_main_loop_new(NULL, FALSE);
 #endif
 
-       g_thread = g_thread_new("muse_core_thread", muse_core_main_loop, g_loop);
-
        server = muse_core_new();
        if (!server) {
                g_main_loop_unref(g_loop);
@@ -491,10 +570,24 @@ int muse_core_run()
                LOGE("Fail to subscribe external storage state change");
 #endif
 
-       LOGD("g_main_loop_run");
-       g_main_loop_run(g_loop);
+       server->watchdog_thread = g_thread_try_new("muse_core_watchdog",
+               _muse_core_main_loop_watchdog, (gpointer)server, NULL);
+       if (server->watchdog_thread) {
+               watchdog_timer_id = g_timeout_add_seconds(MUSE_CORE_WATCHDOG_TIMER_PERIOD,
+                       _muse_core_main_loop_watchdog_timer, (gpointer)server);
+
+               LOGW("g_main_loop_run");
+
+               g_main_loop_run(g_loop);
+
+               g_source_remove(watchdog_timer_id);
+       } else {
+               LOGE("watchdog thread failed");
+               muse_core_log_process_info((int)muse_core_ipc_get_instance()->pid);
+       }
+
+       LOGW("Leave");
 
-       LOGD("Leave");
        return _muse_core_free(server);
 }