Packaging: add missing dependency on pkgconfig
[profile/ivi/node-startup-controller.git] / common / watchdog-client.c
1 /* vi:set et ai sw=2 sts=2 ts=2: */
2 /* -
3  * Copyright (c) 2012 GENIVI.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <systemd/sd-daemon.h>
15
16 #include <glib-object.h>
17 #include <gio/gio.h>
18
19 #include <common/watchdog-client.h>
20
21
22
23 /**
24  * SECTION: watchdog-client
25  * @title: WatchdogClient
26  * @short_description: Notifies the systemd watchdog in regular intervals.
27  * @stability: Internal
28  * 
29  * The #WatchdogClient notifies systemd's watchdog in a regular interval that
30  * is specified upon construction. If the unit file associated with the
31  * application has %WatchdogSec set then systemd will restart the application
32  * if it does not update the watchdog timestamp in this interval (e.g. if it
33  * has crashed or is stuck in an infinite loop).
34  *
35  * In order to avoid problems with delays it is recommended to notify the
36  * systemd watchdog twice in the %WatchdogSec interval, so usually the
37  * value passed to #watchdog_client_new will be half of %WatchdogSec.
38  */
39
40
41
42 /* property identifiers */
43 enum
44 {
45   PROP_0,
46   PROP_TIMEOUT,
47 };
48
49
50
51 static void     watchdog_client_constructed  (GObject      *object);
52 static void     watchdog_client_finalize     (GObject      *object);
53 static void     watchdog_client_get_property (GObject      *object,
54                                               guint         prop_id,
55                                               GValue       *value,
56                                               GParamSpec   *pspec);
57 static void     watchdog_client_set_property (GObject      *object,
58                                               guint         prop_id,
59                                               const GValue *value,
60                                               GParamSpec   *pspec);
61 static gboolean watchdog_client_timeout      (gpointer      user_data);
62
63
64
65 struct _WatchdogClientClass
66 {
67   GObjectClass __parent__;
68 };
69
70 struct _WatchdogClient
71 {
72   GObject          __parent__;
73
74   guint            timeout;
75   guint            timeout_id;
76 };
77
78
79
80 G_DEFINE_TYPE (WatchdogClient, watchdog_client, G_TYPE_OBJECT);
81
82
83
84 static void
85 watchdog_client_class_init (WatchdogClientClass *klass)
86 {
87   GObjectClass *gobject_class;
88
89   gobject_class = G_OBJECT_CLASS (klass);
90   gobject_class->constructed = watchdog_client_constructed;
91   gobject_class->finalize = watchdog_client_finalize;
92   gobject_class->get_property = watchdog_client_get_property;
93   gobject_class->set_property = watchdog_client_set_property;
94
95   g_object_class_install_property (gobject_class,
96                                    PROP_TIMEOUT,
97                                    g_param_spec_uint ("timeout",
98                                                       "timeout",
99                                                       "timeout",
100                                                       0, G_MAXUINT, 120,
101                                                       G_PARAM_READWRITE |
102                                                       G_PARAM_CONSTRUCT_ONLY |
103                                                       G_PARAM_STATIC_STRINGS));
104 }
105
106
107
108 static void
109 watchdog_client_init (WatchdogClient *client)
110 {
111 }
112
113
114
115 static void
116 watchdog_client_constructed (GObject *object)
117 {
118   WatchdogClient *client = WATCHDOG_CLIENT (object);
119
120   /* trigger a systemd watchdog timestap update now */
121   watchdog_client_timeout (client);
122
123   /* schedule a regular timeout to update the systemd watchdog timestamp */
124   client->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
125                                                    client->timeout,
126                                                    watchdog_client_timeout,
127                                                    g_object_ref (client),
128                                                    (GDestroyNotify) g_object_unref);
129 }
130
131
132
133 static void
134 watchdog_client_finalize (GObject *object)
135 {
136   WatchdogClient *client = WATCHDOG_CLIENT (object);
137
138   /* drop the watchdog timeout */
139   if (client->timeout_id > 0)
140     g_source_remove (client->timeout_id);
141
142   (*G_OBJECT_CLASS (watchdog_client_parent_class)->finalize) (object);
143 }
144
145
146
147 static void
148 watchdog_client_get_property (GObject    *object,
149                               guint       prop_id,
150                               GValue     *value,
151                               GParamSpec *pspec)
152 {
153   WatchdogClient *client = WATCHDOG_CLIENT (object);
154
155   switch (prop_id)
156     {
157     case PROP_TIMEOUT:
158       g_value_set_uint (value, client->timeout);
159       break;
160     default:
161       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
162       break;
163     }
164 }
165
166
167
168 static void
169 watchdog_client_set_property (GObject      *object,
170                               guint         prop_id,
171                               const GValue *value,
172                               GParamSpec   *pspec)
173 {
174   WatchdogClient *client = WATCHDOG_CLIENT (object);
175
176   switch (prop_id)
177     {
178     case PROP_TIMEOUT:
179       client->timeout = g_value_get_uint (value);
180       break;
181     default:
182       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
183       break;
184     }
185 }
186
187
188
189 static gboolean
190 watchdog_client_timeout (gpointer user_data)
191 {
192   sd_notify (0, "WATCHDOG=1");
193   return TRUE;
194 }
195
196
197
198 /**
199  * watchdog_client_new:
200  * @timeout: The amount of time to wait in between notifications to systemd's watchdog.
201  * 
202  * Creates a new watchdog and starts notifying systemd's watchdog every @timeout seconds.
203  * 
204  * Returns: A new instance of #WatchdogClient.
205  */
206 WatchdogClient *
207 watchdog_client_new (guint timeout)
208 {
209   return g_object_new (TYPE_WATCHDOG_CLIENT, "timeout", timeout, NULL);
210 }