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