From f860f60771cd4f07ae1d06c56621a5aa8545e60b Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 1 Sep 2020 13:49:27 -0400
Subject: [PATCH] display: Handle failure before display registration
Normally, e.g., gdm-wayland-session would register its display
before starting the session. This display registration is how
the display moves to the "managed" state. We currently detect
session failure in gdm_display_unmanage. If gdm-wayland-session
is killed before it registers the display, gdm_display_unmanage
won't run, and failure won't be detected.
This commit make gdm_display_unmanage get called, even if the
display isn't yet fully managed.
---
daemon/gdm-display.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 7c954ad24..3a260923a 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -648,62 +648,60 @@ gdm_display_disconnect (GdmDisplay *self)
/* resource_id_mask is the bits given to each client for
* addressing resources */
highest_client = (XID) ~unused_bits & ~setup->resource_id_mask;
client_increment = setup->resource_id_mask + 1;
/* Kill every client but ourselves, then close our own connection
*/
for (client = 0;
client <= highest_client;
client += client_increment) {
if (client != setup->resource_id_base)
xcb_kill_client (priv->xcb_connection, client);
}
xcb_flush (priv->xcb_connection);
g_clear_pointer (&priv->xcb_connection, xcb_disconnect);
}
gboolean
gdm_display_unmanage (GdmDisplay *self)
{
GdmDisplayPrivate *priv;
g_return_val_if_fail (GDM_IS_DISPLAY (self), FALSE);
priv = gdm_display_get_instance_private (self);
- g_debug ("GdmDisplay: unmanage display");
-
gdm_display_disconnect (self);
if (priv->user_access_file != NULL) {
gdm_display_access_file_close (priv->user_access_file);
g_object_unref (priv->user_access_file);
priv->user_access_file = NULL;
}
if (priv->access_file != NULL) {
gdm_display_access_file_close (priv->access_file);
g_object_unref (priv->access_file);
priv->access_file = NULL;
}
if (!priv->session_registered) {
g_warning ("GdmDisplay: Session never registered, failing");
_gdm_display_set_status (self, GDM_DISPLAY_FAILED);
} else {
_gdm_display_set_status (self, GDM_DISPLAY_UNMANAGED);
}
return TRUE;
}
gboolean
gdm_display_get_id (GdmDisplay *self,
char **id,
GError **error)
{
GdmDisplayPrivate *priv;
@@ -1446,63 +1444,63 @@ gdm_display_get_object_skeleton (GdmDisplay *self)
{
GdmDisplayPrivate *priv;
priv = gdm_display_get_instance_private (self);
return priv->object_skeleton;
}
static void
on_launch_environment_session_opened (GdmLaunchEnvironment *launch_environment,
GdmDisplay *self)
{
char *session_id;
g_debug ("GdmDisplay: Greeter session opened");
session_id = gdm_launch_environment_get_session_id (launch_environment);
_gdm_display_set_session_id (self, session_id);
g_free (session_id);
}
static void
on_launch_environment_session_started (GdmLaunchEnvironment *launch_environment,
GdmDisplay *self)
{
g_debug ("GdmDisplay: Greeter started");
}
static void
self_destruct (GdmDisplay *self)
{
g_object_ref (self);
- if (gdm_display_get_status (self) == GDM_DISPLAY_MANAGED) {
- gdm_display_unmanage (self);
- }
+
+ g_debug ("GdmDisplay: initiating display self-destruct");
+ gdm_display_unmanage (self);
if (gdm_display_get_status (self) != GDM_DISPLAY_FINISHED) {
queue_finish (self);
}
g_object_unref (self);
}
static void
on_launch_environment_session_stopped (GdmLaunchEnvironment *launch_environment,
GdmDisplay *self)
{
g_debug ("GdmDisplay: Greeter stopped");
self_destruct (self);
}
static void
on_launch_environment_session_exited (GdmLaunchEnvironment *launch_environment,
int code,
GdmDisplay *self)
{
g_debug ("GdmDisplay: Greeter exited: %d", code);
self_destruct (self);
}
static void
on_launch_environment_session_died (GdmLaunchEnvironment *launch_environment,
int signal,
GdmDisplay *self)
{
g_debug ("GdmDisplay: Greeter died: %d", signal);
--
2.31.1