[gnome-settings-daemon/benzea/spawn-in-scope] media-keys: Place spawned processes into a systemd scope
- From: Benjamin Berg <bberg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon/benzea/spawn-in-scope] media-keys: Place spawned processes into a systemd scope
- Date: Tue, 26 Nov 2019 17:21:51 +0000 (UTC)
commit ce9fbdeb1aed8491e1bc6cba23adaef2455d945a
Author: Benjamin Berg <bberg redhat com>
Date: Tue Nov 26 18:20:16 2019 +0100
media-keys: Place spawned processes into a systemd scope
This means we isolate the processes from the media-keys scope itself. We
can also set some default options for the scope, do this using a drop-in
and default to make the process part of graphical-session.target and
kill it after 5 seconds rather than 1min 30s.
data/gsd-launched-override.scope.conf | 6 ++
data/meson.build | 8 +++
meson.build | 1 +
plugins/media-keys/gsd-media-keys-manager.c | 106 ++++++++++++++++++++++++++++
4 files changed, 121 insertions(+)
---
diff --git a/data/gsd-launched-override.scope.conf b/data/gsd-launched-override.scope.conf
new file mode 100644
index 00000000..622787ad
--- /dev/null
+++ b/data/gsd-launched-override.scope.conf
@@ -0,0 +1,6 @@
+[Unit]
+
+PartOf=graphical-session.target
+
+[Scope]
+TimeoutStopSec=5s
diff --git a/data/meson.build b/data/meson.build
index d53eb26c..2e06cfce 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -71,3 +71,11 @@ custom_target('compile-schemas',
output: 'gschemas.compiled',
command: [find_program('glib-compile-schemas'), meson.current_build_dir()],
build_by_default: true)
+
+if enable_systemd
+ install_data(
+ 'gsd-launched-override.scope.conf',
+ rename: 'override.conf',
+ install_dir : join_paths(systemd_userunitdir, 'gsd-launched-.scope.d')
+ )
+endif
diff --git a/meson.build b/meson.build
index 0c65f381..3c59e59d 100644
--- a/meson.build
+++ b/meson.build
@@ -113,6 +113,7 @@ if enable_systemd
# and uncomment systemd_dep below
systemd_userunitdir = join_paths(gsd_prefix, 'lib', 'systemd', 'user')
endif
+config_h.set10('HAVE_SYSTEMD', enable_systemd)
m_dep = cc.find_library('m')
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index 4e167c86..175d55a2 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -264,6 +264,27 @@ G_DEFINE_TYPE_WITH_PRIVATE (GsdMediaKeysManager, gsd_media_keys_manager, G_TYPE_
static gpointer manager_object = NULL;
+#if HAVE_SYSTEMD
+static void
+dbus_call_log_error (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ g_autoptr(GVariant) result;
+ g_autoptr(GError) error = NULL;
+ const gchar *msg = user_data;
+
+ result = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
+ res,
+ &error);
+ if (error) {
+ if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
+ return;
+
+ g_warning ("%s: %s", msg, error->message);
+ }
+}
+#endif
static void
media_key_unref (MediaKey *key)
@@ -996,6 +1017,83 @@ init_kbd (GsdMediaKeysManager *manager)
gnome_settings_profile_end (NULL);
}
+#if HAVE_SYSTEMD
+static void
+app_launched_cb (GAppLaunchContext *context,
+ GAppInfo *info,
+ GVariant *platform_data,
+ gpointer user_data)
+{
+ GsdMediaKeysManager *manager = GSD_MEDIA_KEYS_MANAGER (user_data);
+ GsdMediaKeysManagerPrivate *priv = GSD_MEDIA_KEYS_MANAGER_GET_PRIVATE (manager);
+ gint32 pid;
+ GVariantBuilder builder;
+ const gchar *app_id;
+ g_autofree gchar *unit_name = NULL;
+ g_autoptr(GVariantDict) dict = NULL;
+
+ g_return_if_fail (platform_data != NULL);
+
+ dict = g_variant_dict_new (platform_data);
+
+ g_return_if_fail (g_variant_dict_contains (dict, "pid"));
+
+ if (!g_variant_dict_lookup (dict, "pid", "i", &pid)) {
+ g_critical ("Could not unpack pid from platform data.");
+ return;
+ }
+
+ /* Now that we have the PID, we can create start a transient
+ * scope that wraps it. */
+ g_debug ("Trying to create transient scope for PID %d\n", pid);
+
+ g_assert (priv->connection);
+
+ /* Prepare some information */
+ app_id = g_app_info_get_id (info);
+ if (app_id == NULL) {
+ app_id = "anonymous";
+ }
+ /* This needs to be unique, hopefully the pid will be enough. */
+ unit_name = g_strdup_printf ("gsd-launched-%s-%d.scope", app_id, pid);
+
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ssa(sv)a(sa(sv)))"));
+ g_variant_builder_add (&builder, "s", unit_name);
+ g_variant_builder_add (&builder, "s", "fail");
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(sv)"));
+ /* Note that futher settings are controlled using a drop-in.
+ */
+ g_variant_builder_add (&builder,
+ "(sv)",
+ "Description",
+ g_variant_new_string ("Application launched by gsd-media-keys"));
+ g_variant_builder_add (&builder,
+ "(sv)",
+ "PIDs",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, &pid, 1, 4));
+
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(sa(sv))"));
+ g_variant_builder_close (&builder);
+
+ g_dbus_connection_call (priv->connection,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartTransientUnit",
+ g_variant_builder_end (&builder),
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ 1000,
+ NULL,
+ dbus_call_log_error,
+ "Failed to create transient unit");
+}
+#endif
+
static void
launch_app (GsdMediaKeysManager *manager,
GAppInfo *app_info,
@@ -1009,6 +1107,14 @@ launch_app (GsdMediaKeysManager *manager,
gdk_app_launch_context_set_timestamp (launch_context, timestamp);
set_launch_context_env (manager, G_APP_LAUNCH_CONTEXT (launch_context));
+#if HAVE_SYSTEMD
+ g_signal_connect_object (launch_context,
+ "launched",
+ G_CALLBACK (app_launched_cb),
+ manager,
+ 0);
+#endif
+
if (!g_app_info_launch (app_info, NULL, G_APP_LAUNCH_CONTEXT (launch_context), &error)) {
g_warning ("Could not launch '%s': %s",
g_app_info_get_commandline (app_info),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]