(root)/
glib-2.79.0/
gio/
gmemorymonitordbus.c
       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  {
      63  }
      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  {
      72    guint8 level;
      73  
      74    if (g_strcmp0 (signal_name, "LowMemoryWarning") != 0)
      75      return;
      76    if (parameters == NULL)
      77      return;
      78  
      79    g_variant_get (parameters, "(y)", &level);
      80    g_signal_emit_by_name (dbus, "low-memory-warning", level);
      81  }
      82  
      83  static void
      84  lmm_proxy_cb (GObject      *source_object,
      85                GAsyncResult *res,
      86                gpointer      user_data)
      87  {
      88    GMemoryMonitorDBus *dbus = user_data;
      89    GDBusProxy *proxy;
      90    GError *error = NULL;
      91  
      92    proxy = g_dbus_proxy_new_finish (res, &error);
      93    if (!proxy)
      94      {
      95        g_debug ("Failed to create LowMemoryMonitor D-Bus proxy: %s",
      96                 error->message);
      97        g_error_free (error);
      98        return;
      99      }
     100  
     101    dbus->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal",
     102                                        G_CALLBACK (proxy_signal_cb), dbus);
     103    dbus->proxy = proxy;
     104  
     105  }
     106  
     107  static void
     108  lmm_appeared_cb (GDBusConnection *connection,
     109                   const gchar     *name,
     110                   const gchar     *name_owner,
     111                   gpointer         user_data)
     112  {
     113    GMemoryMonitorDBus *dbus = user_data;
     114  
     115    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  }
     125  
     126  static void
     127  lmm_vanished_cb (GDBusConnection *connection,
     128                   const gchar     *name,
     129                   gpointer         user_data)
     130  {
     131    GMemoryMonitorDBus *dbus = user_data;
     132  
     133    g_clear_signal_handler (&dbus->signal_id, dbus->proxy);
     134    g_clear_object (&dbus->proxy);
     135  }
     136  
     137  static gboolean
     138  g_memory_monitor_dbus_initable_init (GInitable     *initable,
     139                                       GCancellable  *cancellable,
     140                                       GError       **error)
     141  {
     142    GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (initable);
     143  
     144    dbus->cancellable = g_cancellable_new ();
     145    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    return TRUE;
     154  }
     155  
     156  static void
     157  g_memory_monitor_dbus_finalize (GObject *object)
     158  {
     159    GMemoryMonitorDBus *dbus = G_MEMORY_MONITOR_DBUS (object);
     160  
     161    g_cancellable_cancel (dbus->cancellable);
     162    g_clear_object (&dbus->cancellable);
     163    g_clear_signal_handler (&dbus->signal_id, dbus->proxy);
     164    g_clear_object (&dbus->proxy);
     165    g_clear_handle_id (&dbus->watch_id, g_bus_unwatch_name);
     166  
     167    G_OBJECT_CLASS (g_memory_monitor_dbus_parent_class)->finalize (object);
     168  }
     169  
     170  static void
     171  g_memory_monitor_dbus_class_init (GMemoryMonitorDBusClass *nl_class)
     172  {
     173    GObjectClass *gobject_class = G_OBJECT_CLASS (nl_class);
     174  
     175    gobject_class->finalize = g_memory_monitor_dbus_finalize;
     176  }
     177  
     178  static void
     179  g_memory_monitor_dbus_iface_init (GMemoryMonitorInterface *monitor_iface)
     180  {
     181  }
     182  
     183  static void
     184  g_memory_monitor_dbus_initable_iface_init (GInitableIface *iface)
     185  {
     186    iface->init = g_memory_monitor_dbus_initable_init;
     187  }