From f4a1dcfc935598db2f396731a0d59fbf988c1237 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 14 Jun 2019 16:04:44 +0200 Subject: [PATCH] wayland: Set IO error exit handler If this call is available, we can turn libX11 IO errors (fatal by definition) into something we can recover from. Try to dispose all X11 resources and close the display instead, so the compositor can survive the event. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1447 --- config.h.meson | 3 +++ meson.build | 8 ++++++++ src/wayland/meta-xwayland.c | 17 +++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/config.h.meson b/config.h.meson index b2a23596f..f4d6000e1 100644 --- a/config.h.meson +++ b/config.h.meson @@ -71,6 +71,9 @@ /* Whether Xwayland has -initfd option */ #mesondefine HAVE_XWAYLAND_INITFD +/* Whether libX11 has XSetIOErrorExitHandler */ +#mesondefine HAVE_XSETIOERROREXITHANDLER + /* Whether the mkostemp function exists */ #mesondefine HAVE_MKOSTEMP diff --git a/meson.build b/meson.build index 885437931..07b2d0066 100644 --- a/meson.build +++ b/meson.build @@ -424,6 +424,13 @@ if have_wayland endif endif +have_xsetioerrorexithandler = false +if cc.has_function('XSetIOErrorExitHandler', dependencies: x11_dep, + prefix: '''#include ''') + have_xsetioerrorexithandler = true + cdata.set('HAVE_XSETIOERROREXITHANDLER', 1) +endif + optional_functions = [ 'mkostemp', 'posix_fallocate', @@ -495,6 +502,7 @@ output = [ ' Introspection............ ' + have_introspection.to_string(), ' Profiler................. ' + have_profiler.to_string(), ' Xwayland initfd.......... ' + have_xwayland_initfd.to_string(), + ' Safe X11 I/O errors...... ' + have_xsetioerrorexithandler.to_string(), '', ' Tests:', '', diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c index 88a04e5a2..f3dd19260 100644 --- a/src/wayland/meta-xwayland.c +++ b/src/wayland/meta-xwayland.c @@ -334,6 +334,20 @@ x_io_error (Display *display) return 0; } +#ifdef HAVE_XSETIOERROREXITHANDLER +static void +x_io_error_exit (Display *display, + MetaX11Display *x11_display) +{ + MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); + MetaXWaylandManager *manager = &compositor->xwayland_manager; + + g_warning ("Xwayland just died, attempting to recover"); + manager->xserver_grace_period_id = + g_idle_add (shutdown_xwayland_cb, manager); +} +#endif + void meta_xwayland_override_display_number (int number) { @@ -795,6 +809,9 @@ meta_xwayland_complete_init (MetaDisplay *display, we won't reset the tty). */ XSetIOErrorHandler (x_io_error); +#ifdef HAVE_XSETIOERROREXITHANDLER + XSetIOErrorExitHandler (xdisplay, x_io_error_exit, display); +#endif g_signal_connect (display, "x11-display-closing", G_CALLBACK (on_x11_display_closing), NULL);