772bb22b7e5d77e6f8e7e29d9c717e149d0bb065
[platform/core/multimedia/mmsvc-core.git] / server / src / muse_server_watchdog.c
1 /*
2  * muse-server
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: YoungHun Kim <yh8004.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include "muse_server_private.h"
23
24 static gboolean _ms_watchdog_timer_cb(gpointer data);
25 static gpointer _ms_watchdog_thread(gpointer data);
26
27 static gboolean _ms_watchdog_timer_cb(gpointer data)
28 {
29         ms_watchdog_t *watchdog = (ms_watchdog_t *)data;
30
31         muse_return_val_if_fail(watchdog, FALSE);
32
33         g_mutex_lock(&watchdog->lock);
34         g_cond_signal(&watchdog->cond);
35         g_mutex_unlock(&watchdog->lock);
36
37         return TRUE;
38 }
39
40 static gpointer _ms_watchdog_thread(gpointer data)
41 {
42         ms_watchdog_t *watchdog = (ms_watchdog_t *)data;
43         gint64 end_time = 0;
44         guint try_count = 0;
45         char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
46
47         muse_return_val_if_fail(watchdog, NULL);
48
49         LOGW("watchdog start : %p", watchdog);
50
51         while (watchdog->run) {
52                 g_mutex_lock(&watchdog->lock);
53
54                 end_time = g_get_monotonic_time() + G_TIME_SPAN_SECOND * MS_WATCHDOG_CHECK_PERIOD;
55                 if (g_cond_wait_until(&watchdog->cond, &watchdog->lock, end_time)) {
56                         try_count = 0;
57                 } else {
58                         try_count++;
59                         LOGW("[%d / %d] timeout", try_count, MS_WATCHDOG_CHECK_COUNT);
60                 }
61
62                 if (try_count >= MS_WATCHDOG_CHECK_COUNT) {
63                         snprintf(err_msg, sizeof(err_msg), "NO RESPONSE OF MAINLOOP");
64                         LOGE("%s", err_msg);
65                         g_mutex_unlock(&watchdog->lock);
66                         ms_terminate(SIGABRT);
67                 }
68
69                 g_mutex_unlock(&watchdog->lock);
70         }
71
72         LOGW("Leave");
73
74         return NULL;
75 }
76
77 int ms_watchdog_init(ms_watchdog_t *watchdog)
78 {
79         muse_return_val_if_fail(watchdog, MM_ERROR_INVALID_ARGUMENT);
80
81         g_mutex_init(&watchdog->lock);
82         g_cond_init(&watchdog->cond);
83         watchdog->run = TRUE;
84
85         return MM_ERROR_NONE;
86 }
87
88 int ms_watchdog_deinit(ms_watchdog_t *watchdog)
89 {
90         muse_return_val_if_fail(watchdog, MM_ERROR_INVALID_ARGUMENT);
91
92         g_mutex_clear(&watchdog->lock);
93         g_cond_clear(&watchdog->cond);
94
95         return MM_ERROR_NONE;
96 }
97
98 gboolean ms_watchdog_attach(ms_watchdog_t *watchdog)
99 {
100         muse_return_val_if_fail(watchdog, FALSE);
101
102         watchdog->thread = g_thread_try_new("muse_watchdog",
103                                                                                 _ms_watchdog_thread,
104                                                                                 (gpointer)watchdog,
105                                                                                 NULL);
106         if (watchdog->thread) {
107                 watchdog->timer_id = g_timeout_add_seconds(MS_WATCHDOG_TIMER_PERIOD,
108                                                                                                 _ms_watchdog_timer_cb,
109                                                                                                 (gpointer)watchdog);
110                 return TRUE;
111         }
112
113         return FALSE;
114 }
115
116 int ms_watchdog_detach(ms_watchdog_t *watchdog)
117 {
118         gboolean rm_success = FALSE;
119
120         muse_return_val_if_fail(watchdog, MM_ERROR_INVALID_ARGUMENT);
121
122         g_mutex_lock(&watchdog->lock);
123         watchdog->run = FALSE;
124         g_cond_signal(&watchdog->cond);
125         g_mutex_unlock(&watchdog->lock);
126
127         LOGW("join watchdog thread - start");
128
129         g_thread_join(watchdog->thread);
130         watchdog->thread = NULL;
131
132         LOGW("join watchdog thread - done");
133
134         rm_success = g_source_remove(watchdog->timer_id);
135         if (!rm_success) {
136                 LOGE("Failed to remove %d", watchdog->timer_id);
137                 return MM_ERROR_UNKNOWN;
138         }
139
140         return MM_ERROR_NONE;
141 }