From 3073c23c673ede5093c1f93fb0775c2cd3203d7f Mon Sep 17 00:00:00 2001 From: Ray Strode 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