Doxygen Book
nnstreamer_watchdog.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: LGPL-2.1-only */
15 #include <nnstreamer_log.h>
16 #include "nnstreamer_watchdog.h"
17 
21 typedef struct _NnstWatchdog
22 {
23  GMainContext *context;
24  GMainLoop *loop;
25  GThread *thread;
26  GSource *source;
27  GMutex lock;
28  GCond cond;
29 } NnstWatchdog;
30 
34 static gboolean
36 {
37  g_mutex_lock (&watchdog->lock);
38  g_cond_signal (&watchdog->cond);
39  g_mutex_unlock (&watchdog->lock);
40 
41  return G_SOURCE_REMOVE;
42 }
43 
47 static gpointer
49 {
50  NnstWatchdog *watchdog = (NnstWatchdog *) ptr;
51  GSource *idle_source;
52 
53  g_main_context_push_thread_default (watchdog->context);
54 
55  idle_source = g_idle_source_new ();
56  g_source_set_callback (idle_source,
57  (GSourceFunc) _loop_running_cb, watchdog, NULL);
58  g_source_attach (idle_source, watchdog->context);
59  g_source_unref (idle_source);
60 
61  g_main_loop_run (watchdog->loop);
62 
63  g_main_context_pop_thread_default (watchdog->context);
64 
65  return NULL;
66 }
67 
71 gboolean
73 {
74  gint64 end_time;
75  gboolean ret = TRUE;
76  GError *error = NULL;
77  NnstWatchdog *watchdog;
78 
79  if (!watchdog_h) {
80  ml_loge ("Invalid parameter: watchdog handle is NULL.");
81  return FALSE;
82  }
83 
84  watchdog = g_try_new0 (NnstWatchdog, 1);
85  if (!watchdog) {
86  ml_loge ("Failed to allocate memory for watchdog.");
87  return FALSE;
88  }
89 
90  watchdog->context = g_main_context_new ();
91  watchdog->loop = g_main_loop_new (watchdog->context, FALSE);
92 
93  g_mutex_init (&watchdog->lock);
94  g_cond_init (&watchdog->cond);
95  g_mutex_lock (&watchdog->lock);
96  watchdog->thread =
97  g_thread_try_new ("suspend_watchdog", _nnstreamer_watchdog_thread,
98  watchdog, &error);
99 
100  if (!watchdog->thread) {
101  ml_loge ("Failed to create watchdog thread: %s", error->message);
102  g_clear_error (&error);
103  ret = FALSE;
104  goto done;
105  }
106 
107  end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
108  while (!g_main_loop_is_running (watchdog->loop)) {
109  if (!g_cond_wait_until (&watchdog->cond, &watchdog->lock, end_time)) {
110  ml_loge ("Failed to wait main loop running.");
111  ret = FALSE;
112  goto done;
113  }
114  }
115 
116 done:
117  g_mutex_unlock (&watchdog->lock);
118  g_mutex_clear (&watchdog->lock);
119  g_cond_clear (&watchdog->cond);
120  if (!ret) {
121  nnstreamer_watchdog_destroy (watchdog);
122  watchdog = NULL;
123  }
124  *watchdog_h = watchdog;
125 
126  return ret;
127 }
128 
132 void
134 {
135  NnstWatchdog *watchdog = (NnstWatchdog *) watchdog_h;
136  nnstreamer_watchdog_release (watchdog);
137 
138  if (watchdog && watchdog->context) {
139  g_main_loop_quit (watchdog->loop);
140  g_thread_join (watchdog->thread);
141  watchdog->thread = NULL;
142 
143  g_main_loop_unref (watchdog->loop);
144  watchdog->loop = NULL;
145 
146  g_main_context_unref (watchdog->context);
147  watchdog->context = NULL;
148 
149  g_free (watchdog_h);
150  }
151 }
152 
156 void
158 {
159  NnstWatchdog *watchdog = (NnstWatchdog *) watchdog_h;
160  if (watchdog && watchdog->source) {
161  g_source_destroy (watchdog->source);
162  g_source_unref (watchdog->source);
163  watchdog->source = NULL;
164  }
165 }
166 
170 gboolean
171 nnstreamer_watchdog_feed (nns_watchdog_h watchdog_h, GSourceFunc func,
172  guint interval, void *user_data)
173 {
174  NnstWatchdog *watchdog = (NnstWatchdog *) watchdog_h;
175 
176  if (!watchdog || !func) {
177  ml_loge ("Invalid parameter: watchdog handle or func is NULL.");
178  return FALSE;
179  }
180 
181  if (watchdog->context) {
182  watchdog->source = g_timeout_source_new (interval);
183  g_source_set_callback (watchdog->source, func, user_data, NULL);
184  g_source_attach (watchdog->source, watchdog->context);
185  } else {
186  ml_loge
187  ("Failed to feed to watchdog. Watchdog is not created or context is invalid.");
188  return FALSE;
189  }
190 
191  return TRUE;
192 }
_NnstWatchdog::loop
GMainLoop * loop
Definition: nnstreamer_watchdog.c:24
FALSE
return FALSE
Definition: gsttensor_transform.c:590
nnstreamer_watchdog_release
void nnstreamer_watchdog_release(nns_watchdog_h watchdog_h)
Release watchdog source. Recommended using watchdog handle with proper lock (e.g.,...
Definition: nnstreamer_watchdog.c:157
nnstreamer_log.h
Internal log util for NNStreamer plugins and native APIs.
_nnstreamer_watchdog_thread
static gpointer _nnstreamer_watchdog_thread(gpointer ptr)
Watchdog thread.
Definition: nnstreamer_watchdog.c:48
g_free
g_free(self->option[(opnum) - 1])
opnum: \
nnstreamer_watchdog_feed
gboolean nnstreamer_watchdog_feed(nns_watchdog_h watchdog_h, GSourceFunc func, guint interval, void *user_data)
Set watchdog timeout. Recommended using watchdog handle with proper lock (e.g., GST_OBJECT_LOCK())
Definition: nnstreamer_watchdog.c:171
_NnstWatchdog::lock
GMutex lock
Definition: nnstreamer_watchdog.c:27
ml_loge
#define ml_loge
Definition: nnstreamer_log.h:78
nnstreamer_watchdog.h
NNStreamer watchdog header to manage the schedule in the element.
nnstreamer_watchdog_destroy
void nnstreamer_watchdog_destroy(nns_watchdog_h watchdog_h)
Destroy watchdog source. Recommended using watchdog handle with proper lock (e.g.,...
Definition: nnstreamer_watchdog.c:133
TRUE
return TRUE
Definition: gsttensor_if.c:897
_NnstWatchdog::cond
GCond cond
Definition: nnstreamer_watchdog.c:28
nnstreamer_watchdog_create
gboolean nnstreamer_watchdog_create(nns_watchdog_h *watchdog_h)
Create nnstreamer watchdog. Recommended using watchdog handle with proper lock (e....
Definition: nnstreamer_watchdog.c:72
NnstWatchdog
struct _NnstWatchdog NnstWatchdog
Structure for NNStreamer watchdog.
_NnstWatchdog
Structure for NNStreamer watchdog.
Definition: nnstreamer_watchdog.c:21
_NnstWatchdog::thread
GThread * thread
Definition: nnstreamer_watchdog.c:25
_NnstWatchdog::source
GSource * source
Definition: nnstreamer_watchdog.c:26
nns_watchdog_h
void * nns_watchdog_h
Definition: nnstreamer_watchdog.h:25
_NnstWatchdog::context
GMainContext * context
Definition: nnstreamer_watchdog.c:23
_loop_running_cb
static gboolean _loop_running_cb(NnstWatchdog *watchdog)
Called when loop is running.
Definition: nnstreamer_watchdog.c:35