Coverage Report

Created: 2025-07-01 07:09

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