Blob Blame History Raw
From 3073c23c673ede5093c1f93fb0775c2cd3203d7f Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 30 Aug 2018 16:09:02 -0400
Subject: [PATCH 28/51] gdm-wayland-session,gdm-x-session: register after delay

Right now gdm-x-session registers with GDM as soon as the
X server is started, and gdm-wayland-session registers as
soon as the session is started.

Ideally registration wouldn't happen until the session
says things started successfully.

This commit inches us toward that ideal but adding a little
timeout before proceeding with registration.

A future commit will add a new xsession file key to allow
us to know whether or not the session manager of the session
supports doing registration.
---
 daemon/gdm-wayland-session.c | 23 ++++++++++++++++-------
 daemon/gdm-x-session.c       | 25 +++++++++++++++++--------
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/daemon/gdm-wayland-session.c b/daemon/gdm-wayland-session.c
index 94f49e19c..de1991b34 100644
--- a/daemon/gdm-wayland-session.c
+++ b/daemon/gdm-wayland-session.c
@@ -427,60 +427,75 @@ init_state (State **state)
         static State state_allocation;
 
         *state = &state_allocation;
 }
 
 static void
 clear_state (State **out_state)
 {
         State *state = *out_state;
 
         g_clear_object (&state->cancellable);
         g_clear_object (&state->bus_connection);
         g_clear_object (&state->session_subprocess);
         g_clear_pointer (&state->environment, g_strfreev);
         g_clear_pointer (&state->main_loop, g_main_loop_unref);
         *out_state = NULL;
 }
 
 static gboolean
 on_sigterm (State *state)
 {
         g_cancellable_cancel (state->cancellable);
 
         if (g_main_loop_is_running (state->main_loop)) {
                 g_main_loop_quit (state->main_loop);
         }
 
         return G_SOURCE_CONTINUE;
 }
 
+static gboolean
+on_registration_delay_complete (State *state)
+{
+        gboolean ret;
+
+        ret = register_display (state, state->cancellable);
+
+        if (!ret) {
+                g_printerr ("Unable to register display with display manager\n");
+                g_main_loop_quit (state->main_loop);
+        }
+
+        return G_SOURCE_REMOVE;
+}
+
 int
 main (int    argc,
       char **argv)
 {
         State           *state = NULL;
         GOptionContext  *context = NULL;
         static char    **args = NULL;
         gboolean         debug = FALSE;
         gboolean         ret;
         int              exit_status = EX_OK;
         static GOptionEntry entries []   = {
                 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
                 { NULL }
         };
 
         bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
         textdomain (GETTEXT_PACKAGE);
         setlocale (LC_ALL, "");
 
         gdm_log_init ();
 
         context = g_option_context_new (_("GNOME Display Manager Wayland Session Launcher"));
         g_option_context_add_main_entries (context, entries, NULL);
 
         g_option_context_parse (context, &argc, &argv, NULL);
         g_option_context_free (context);
 
         if (args == NULL || args[0] == NULL || args[1] != NULL) {
                 g_warning ("gdm-wayland-session takes one argument (the session)");
                 exit_status = EX_USAGE;
@@ -501,55 +516,49 @@ main (int    argc,
         }
 
         gdm_settings_direct_get_boolean (GDM_KEY_DEBUG, &debug);
         state->debug_enabled = debug;
 
         gdm_log_set_debug (debug);
 
         state->main_loop = g_main_loop_new (NULL, FALSE);
         state->cancellable = g_cancellable_new ();
 
         g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state);
 
         ret = spawn_bus (state, state->cancellable);
 
         if (!ret) {
                 g_printerr ("Unable to run session message bus\n");
                 exit_status = EX_SOFTWARE;
                 goto out;
         }
 
         import_environment (state, state->cancellable);
 
         ret = spawn_session (state, state->cancellable);
 
         if (!ret) {
                 g_printerr ("Unable to run session\n");
                 exit_status = EX_SOFTWARE;
                 goto out;
         }
 
-        ret = register_display (state, state->cancellable);
-
-        if (!ret) {
-                g_printerr ("Unable to register display with display manager\n");
-                exit_status = EX_SOFTWARE;
-                goto out;
-        }
+        g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state);
 
         g_main_loop_run (state->main_loop);
 
         /* Only use exit status of session if we're here because it exit */
 
         if (state->session_subprocess == NULL) {
                 exit_status = state->session_exit_status;
         }
 
 out:
         if (state != NULL) {
                 signal_subprocesses (state);
                 wait_on_subprocesses (state);
                 clear_state (&state);
         }
 
         return exit_status;
 }
diff --git a/daemon/gdm-x-session.c b/daemon/gdm-x-session.c
index 3b2fcef47..412999cf5 100644
--- a/daemon/gdm-x-session.c
+++ b/daemon/gdm-x-session.c
@@ -783,60 +783,75 @@ init_state (State **state)
 }
 
 static void
 clear_state (State **out_state)
 {
         State *state = *out_state;
 
         g_clear_object (&state->cancellable);
         g_clear_object (&state->bus_connection);
         g_clear_object (&state->session_subprocess);
         g_clear_object (&state->x_subprocess);
         g_clear_pointer (&state->environment, g_strfreev);
         g_clear_pointer (&state->auth_file, g_free);
         g_clear_pointer (&state->display_name, g_free);
         g_clear_pointer (&state->main_loop, g_main_loop_unref);
         *out_state = NULL;
 }
 
 static gboolean
 on_sigterm (State *state)
 {
         g_cancellable_cancel (state->cancellable);
 
         if (g_main_loop_is_running (state->main_loop)) {
                 g_main_loop_quit (state->main_loop);
         }
 
         return G_SOURCE_CONTINUE;
 }
 
+static gboolean
+on_registration_delay_complete (State *state)
+{
+        gboolean ret;
+
+        ret = register_display (state, state->cancellable);
+
+        if (!ret) {
+                g_printerr ("Unable to register display with display manager\n");
+                g_main_loop_quit (state->main_loop);
+        }
+
+        return G_SOURCE_REMOVE;
+}
+
 int
 main (int    argc,
       char **argv)
 {
         State           *state = NULL;
         GOptionContext  *context = NULL;
         static char    **args = NULL;
         static gboolean  run_script = FALSE;
         static gboolean  allow_remote_connections = FALSE;
         gboolean         debug = FALSE;
         gboolean         ret;
         int              exit_status = EX_OK;
         static GOptionEntry entries []   = {
                 { "run-script", 'r', 0, G_OPTION_ARG_NONE, &run_script, N_("Run program through /etc/gdm/Xsession wrapper script"), NULL },
                 { "allow-remote-connections", 'a', 0, G_OPTION_ARG_NONE, &allow_remote_connections, N_("Listen on TCP socket"), NULL },
                 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args, "", "" },
                 { NULL }
         };
 
         bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
         textdomain (GETTEXT_PACKAGE);
         setlocale (LC_ALL, "");
 
         gdm_log_init ();
 
         context = g_option_context_new (_("GNOME Display Manager X Session Launcher"));
         g_option_context_add_main_entries (context, entries, NULL);
 
         g_option_context_parse (context, &argc, &argv, NULL);
         g_option_context_free (context);
@@ -869,63 +884,57 @@ main (int    argc,
         state->cancellable = g_cancellable_new ();
 
         g_unix_signal_add (SIGTERM, (GSourceFunc) on_sigterm, state);
 
         ret = spawn_x_server (state, allow_remote_connections, state->cancellable);
 
         if (!ret) {
                 g_printerr ("Unable to run X server\n");
                 exit_status = EX_SOFTWARE;
                 goto out;
         }
 
         ret = spawn_bus (state, state->cancellable);
 
         if (!ret) {
                 g_printerr ("Unable to run session message bus\n");
                 exit_status = EX_SOFTWARE;
                 goto out;
         }
 
         import_environment (state, state->cancellable);
 
         ret = update_bus_environment (state, state->cancellable);
 
         if (!ret) {
                 g_printerr ("Unable to update bus environment\n");
                 exit_status = EX_SOFTWARE;
                 goto out;
         }
 
-        ret = register_display (state, state->cancellable);
-
-        if (!ret) {
-                g_printerr ("Unable to register display with display manager\n");
-                exit_status = EX_SOFTWARE;
-                goto out;
-        }
-
         ret = spawn_session (state, run_script, state->cancellable);
 
         if (!ret) {
                 g_printerr ("Unable to run session\n");
                 exit_status = EX_SOFTWARE;
                 goto out;
         }
 
+        g_timeout_add_seconds (2, (GSourceFunc) on_registration_delay_complete, state);
+
         g_main_loop_run (state->main_loop);
 
         /* Only use exit status of session if we're here because it exit */
 
         if (state->session_subprocess == NULL) {
                 exit_status = state->session_exit_status;
         }
 
 out:
         if (state != NULL) {
                 signal_subprocesses (state);
                 wait_on_subprocesses (state);
                 clear_state (&state);
         }
 
         return exit_status;
 }
-- 
2.27.0