[mutter] window: Add cgroup management to MetaWindow
- From: Marge Bot <marge-bot src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] window: Add cgroup management to MetaWindow
- Date: Thu, 2 Sep 2021 22:24:43 +0000 (UTC)
commit c2efe255972a3a29e1e2ba5fde5519440aaba653
Author: Nishal Kulkarni <nishalkulkarni gmail com>
Date: Thu Aug 5 20:05:18 2021 +0530
window: Add cgroup management to MetaWindow
Currently the only way to get cgroup for a MetaWindow is to get it's
PID and perform a bunch of file accesses and string manipulations.
This is especially not feasible if we want to get the cgroup every
time a MetaWindow has gained or lost focus.
A solution to this is to cache the GFile for a cgroup path.
The creation and access of this GFile is handled by
`meta_window_get_unit_cgroup` function.
`meta_window_unit_cgroup_equal` is a utility function which allows
us to compare whether two MetaWindows belong to the same cgroup.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1960>
src/core/window-private.h | 7 +++++
src/core/window.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)
---
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 18f62d1f45..3bd75fe47a 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -565,6 +565,9 @@ struct _MetaWindow
guint unmanage_idle_id;
pid_t client_pid;
+
+ gboolean has_valid_cgroup;
+ GFile *cgroup_path;
};
struct _MetaWindowClass
@@ -890,4 +893,8 @@ gboolean meta_window_shortcuts_inhibited (MetaWindow *window,
ClutterInputDevice *source);
gboolean meta_window_is_stackable (MetaWindow *window);
gboolean meta_window_is_focus_async (MetaWindow *window);
+
+GFile *meta_window_get_unit_cgroup (MetaWindow *window);
+gboolean meta_window_unit_cgroup_equal (MetaWindow *window1,
+ MetaWindow *window2);
#endif
diff --git a/src/core/window.c b/src/core/window.c
index b23f66e814..e543814179 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -97,6 +97,10 @@
#include "wayland/meta-window-xwayland.h"
#endif
+#ifdef HAVE_LIBSYSTEMD
+#include <systemd/sd-login.h>
+#endif
+
/* Windows that unmaximize to a size bigger than that fraction of the workarea
* will be scaled down to that size (while maintaining aspect ratio).
* Windows that cover an area greater then this size are automaximized on map.
@@ -332,6 +336,9 @@ meta_window_finalize (GObject *object)
if (window->transient_for)
g_object_unref (window->transient_for);
+ if (window->cgroup_path)
+ g_object_unref (window->cgroup_path);
+
g_free (window->sm_client_id);
g_free (window->wm_client_machine);
g_free (window->startup_id);
@@ -1157,6 +1164,9 @@ _meta_window_shared_new (MetaDisplay *display,
window->client_pid = 0;
+ window->has_valid_cgroup = TRUE;
+ window->cgroup_path = NULL;
+
window->xtransient_for = None;
window->xclient_leader = None;
@@ -7736,6 +7746,75 @@ meta_window_get_pid (MetaWindow *window)
return window->client_pid;
}
+/**
+ * meta_window_get_unit_cgroup:
+ * @window: a #MetaWindow
+ *
+ * Return value: a GFile for the cgroup path, or NULL.
+ */
+GFile *
+meta_window_get_unit_cgroup (MetaWindow *window)
+{
+#ifdef HAVE_LIBSYSTEMD
+ g_autofree char *contents = NULL;
+ g_autofree char *complete_path = NULL;
+ g_autofree char *unit_name = NULL;
+ g_autofree char *unit_path = NULL;
+ char *unit_end;
+ pid_t pid;
+
+ if (!window->has_valid_cgroup)
+ return NULL;
+
+ if (window->cgroup_path)
+ return window->cgroup_path;
+
+ pid = meta_window_get_pid (window);
+ if (pid < 1)
+ return NULL;
+
+ if (sd_pid_get_cgroup (pid, &contents) < 0)
+ {
+ window->has_valid_cgroup = FALSE;
+ return NULL;
+ }
+ g_strstrip (contents);
+
+ complete_path = g_strdup_printf ("%s%s", "/sys/fs/cgroup", contents);
+
+ if (sd_pid_get_user_unit (pid, &unit_name) < 0)
+ {
+ window->has_valid_cgroup = FALSE;
+ return NULL;
+ }
+ g_strstrip (unit_name);
+
+ unit_end = strstr (complete_path, unit_name) + strlen (unit_name);
+ *unit_end = '\0';
+
+ window->cgroup_path = g_file_new_for_path (complete_path);
+
+ return window->cgroup_path;
+#else
+ return NULL;
+#endif
+}
+
+gboolean
+meta_window_unit_cgroup_equal (MetaWindow *window1,
+ MetaWindow *window2)
+{
+ GFile *window1_file, *window2_file;
+
+ window1_file = meta_window_get_unit_cgroup (window1);
+ window2_file = meta_window_get_unit_cgroup (window2);
+
+ if (!window1_file || !window2_file)
+ return FALSE;
+
+ return g_file_equal (window1_file, window2_file);
+}
+
/**
* meta_window_get_client_machine:
* @window: a #MetaWindow
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]