Coverage Report

Created: 2025-06-13 06:55

/src/glib/gio/gmemorymonitordbus.c
Line
Count
Source (jump to first uncovered line)
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
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
g_memory_monitor_dbus_init (GMemoryMonitorDBus *dbus)
62
0
{
63
0
}
64
65
static void
66
proxy_signal_cb (GDBusProxy         *proxy,
67
                 const gchar        *sender_name,
68
                 const gchar        *signal_name,
69
                 GVariant           *parameters,
70
                 GMemoryMonitorDBus *dbus)
71
0
{
72
0
  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
0
}
82
83
static void
84
lmm_proxy_cb (GObject      *source_object,
85
              GAsyncResult *res,
86
              gpointer      user_data)
87
0
{
88
0
  GMemoryMonitorDBus *dbus = user_data;
89
0
  GDBusProxy *proxy;
90
0
  GError *error = NULL;
91
92
0
  proxy = g_dbus_proxy_new_finish (res, &error);
93
0
  if (!proxy)
94
0
    {
95
0
      g_debug ("Failed to create LowMemoryMonitor D-Bus proxy: %s",
96
0
               error->message);
97
0
      g_error_free (error);
98
0
      return;
99
0
    }
100
101
0
  dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal",
102
0
                                      G_CALLBACK (proxy_signal_cb), dbus);
103
0
  dbus->proxy = proxy;
104
105
0
}
106
107
static void
108
lmm_appeared_cb (GDBusConnection *connection,
109
                 const gchar     *name,
110
                 const gchar     *name_owner,
111
                 gpointer         user_data)
112
0
{
113
0
  GMemoryMonitorDBus *dbus = user_data;
114
115
0
  g_dbus_proxy_new (connection,
116
0
                    G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
117
0
                    NULL,
118
0
                    "org.freedesktop.LowMemoryMonitor",
119
0
                    "/org/freedesktop/LowMemoryMonitor",
120
0
                    "org.freedesktop.LowMemoryMonitor",
121
0
                    dbus->cancellable,
122
0
                    lmm_proxy_cb,
123
0
                    dbus);
124
0
}
125
126
static void
127
lmm_vanished_cb (GDBusConnection *connection,
128
                 const gchar     *name,
129
                 gpointer         user_data)
130
0
{
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
g_memory_monitor_dbus_initable_init (GInitable     *initable,
139
                                     GCancellable  *cancellable,
140
                                     GError       **error)
141
0
{
142
0
  GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (initable);
143
144
0
  dbus->cancellable = g_cancellable_new ();
145
0
  dbus->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
146
0
                                     "org.freedesktop.LowMemoryMonitor",
147
0
                                     G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
148
0
                                     lmm_appeared_cb,
149
0
                                     lmm_vanished_cb,
150
0
                                     dbus,
151
0
                                     NULL);
152
153
0
  return TRUE;
154
0
}
155
156
static void
157
g_memory_monitor_dbus_finalize (GObject *object)
158
0
{
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
g_memory_monitor_dbus_class_init (GMemoryMonitorDBusClass *nl_class)
172
0
{
173
0
  GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);
174
175
0
  gobject_class->finalize = g_memory_monitor_dbus_finalize;
176
0
}
177
178
static void
179
g_memory_monitor_dbus_iface_init (GMemoryMonitorInterface *monitor_iface)
180
0
{
181
0
}
182
183
static void
184
g_memory_monitor_dbus_initable_iface_init (GInitableIface *iface)
185
0
{
186
0
  iface->init = g_memory_monitor_dbus_initable_init;
187
0
}