Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright 2019 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include "config.h"
22 : :
23 : : #include "gmemorymonitor.h"
24 : : #include "gmemorymonitordbus.h"
25 : : #include "gioerror.h"
26 : : #include "ginitable.h"
27 : : #include "giomodule-priv.h"
28 : : #include "glibintl.h"
29 : : #include "glib/gstdio.h"
30 : : #include "gcancellable.h"
31 : : #include "gdbusproxy.h"
32 : : #include "gdbusnamewatching.h"
33 : :
34 : : #define G_MEMORY_MONITOR_DBUS_GET_INITABLE_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), G_TYPE_INITABLE, GInitable))
35 : :
36 : : static void g_memory_monitor_dbus_iface_init (GMemoryMonitorInterface *iface);
37 : : static void g_memory_monitor_dbus_initable_iface_init (GInitableIface *iface);
38 : :
39 : : struct _GMemoryMonitorDBus
40 : : {
41 : : GObject parent_instance;
42 : :
43 : : guint watch_id;
44 : : GCancellable *cancellable;
45 : : GDBusProxy *proxy;
46 : : gulong signal_id;
47 : : };
48 : :
49 : 240 : G_DEFINE_TYPE_WITH_CODE (GMemoryMonitorDBus, g_memory_monitor_dbus, G_TYPE_OBJECT,
50 : : G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
51 : : g_memory_monitor_dbus_initable_iface_init)
52 : : G_IMPLEMENT_INTERFACE (G_TYPE_MEMORY_MONITOR,
53 : : g_memory_monitor_dbus_iface_init)
54 : : _g_io_modules_ensure_extension_points_registered ();
55 : : g_io_extension_point_implement (G_MEMORY_MONITOR_EXTENSION_POINT_NAME,
56 : : g_define_type_id,
57 : : "dbus",
58 : : 30))
59 : :
60 : : static void
61 : 1 : g_memory_monitor_dbus_init (GMemoryMonitorDBus *dbus)
62 : : {
63 : 1 : }
64 : :
65 : : static void
66 : 0 : proxy_signal_cb (GDBusProxy *proxy,
67 : : const gchar *sender_name,
68 : : const gchar *signal_name,
69 : : GVariant *parameters,
70 : : GMemoryMonitorDBus *dbus)
71 : : {
72 : : guint8 level;
73 : :
74 : 0 : if (g_strcmp0 (signal_name, "LowMemoryWarning") != 0)
75 : 0 : return;
76 : 0 : if (parameters == NULL)
77 : 0 : return;
78 : :
79 : 0 : g_variant_get (parameters, "(y)", &level);
80 : 0 : g_signal_emit_by_name (dbus, "low-memory-warning", level);
81 : : }
82 : :
83 : : static void
84 : 0 : lmm_proxy_cb (GObject *source_object,
85 : : GAsyncResult *res,
86 : : gpointer user_data)
87 : : {
88 : 0 : GMemoryMonitorDBus *dbus = user_data;
89 : : GDBusProxy *proxy;
90 : 0 : GError *error = NULL;
91 : :
92 : 0 : proxy = g_dbus_proxy_new_finish (res, &error);
93 : 0 : if (!proxy)
94 : : {
95 : 0 : g_debug ("Failed to create LowMemoryMonitor D-Bus proxy: %s",
96 : : error->message);
97 : 0 : g_error_free (error);
98 : 0 : return;
99 : : }
100 : :
101 : 0 : dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal",
102 : : G_CALLBACK (proxy_signal_cb), dbus);
103 : 0 : dbus->proxy = proxy;
104 : :
105 : : }
106 : :
107 : : static void
108 : 0 : lmm_appeared_cb (GDBusConnection *connection,
109 : : const gchar *name,
110 : : const gchar *name_owner,
111 : : gpointer user_data)
112 : : {
113 : 0 : GMemoryMonitorDBus *dbus = user_data;
114 : :
115 : 0 : g_dbus_proxy_new (connection,
116 : : G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
117 : : NULL,
118 : : "org.freedesktop.LowMemoryMonitor",
119 : : "/org/freedesktop/LowMemoryMonitor",
120 : : "org.freedesktop.LowMemoryMonitor",
121 : : dbus->cancellable,
122 : : lmm_proxy_cb,
123 : : dbus);
124 : 0 : }
125 : :
126 : : static void
127 : 0 : lmm_vanished_cb (GDBusConnection *connection,
128 : : const gchar *name,
129 : : gpointer user_data)
130 : : {
131 : 0 : GMemoryMonitorDBus *dbus = user_data;
132 : :
133 : 0 : g_clear_signal_handler (&dbus->signal_id, dbus->proxy);
134 : 0 : g_clear_object (&dbus->proxy);
135 : 0 : }
136 : :
137 : : static gboolean
138 : 1 : g_memory_monitor_dbus_initable_init (GInitable *initable,
139 : : GCancellable *cancellable,
140 : : GError **error)
141 : : {
142 : 1 : GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (initable);
143 : :
144 : 1 : dbus->cancellable = g_cancellable_new ();
145 : 1 : dbus->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
146 : : "org.freedesktop.LowMemoryMonitor",
147 : : G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
148 : : lmm_appeared_cb,
149 : : lmm_vanished_cb,
150 : : dbus,
151 : : NULL);
152 : :
153 : 1 : return TRUE;
154 : : }
155 : :
156 : : static void
157 : 0 : g_memory_monitor_dbus_finalize (GObject *object)
158 : : {
159 : 0 : GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (object);
160 : :
161 : 0 : g_cancellable_cancel (dbus->cancellable);
162 : 0 : g_clear_object (&dbus->cancellable);
163 : 0 : g_clear_signal_handler (&dbus->signal_id, dbus->proxy);
164 : 0 : g_clear_object (&dbus->proxy);
165 : 0 : g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name);
166 : :
167 : 0 : G_OBJECT_CLASS (g_memory_monitor_dbus_parent_class)->finalize (object);
168 : 0 : }
169 : :
170 : : static void
171 : 1 : g_memory_monitor_dbus_class_init (GMemoryMonitorDBusClass *nl_class)
172 : : {
173 : 1 : GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);
174 : :
175 : 1 : gobject_class->finalize = g_memory_monitor_dbus_finalize;
176 : 1 : }
177 : :
178 : : static void
179 : 1 : g_memory_monitor_dbus_iface_init (GMemoryMonitorInterface *monitor_iface)
180 : : {
181 : 1 : }
182 : :
183 : : static void
184 : 1 : g_memory_monitor_dbus_initable_iface_init (GInitableIface *iface)
185 : : {
186 : 1 : iface->init = g_memory_monitor_dbus_initable_init;
187 : 1 : }
|