From ef366c5fcbbe624c983f8b2465ac16e7c80745c5 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 1 Sep 2023 01:14:21 +0200 Subject: [PATCH] mtk: Make error traps multi-display Keep a per-display list of error traps, so we don't mix them together, and possibly deem unintended error traps outdated. This means init/deinit calls are now stackable, and need to happen evenly. In order to honor this, move the MetaX11Display error trap destrution to finalize. Part-of: --- mtk/mtk/mtk-x11-errors.c | 46 ++++++++++++++++++++++++++++++++------ src/x11/meta-x11-display.c | 13 +++++++++-- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/mtk/mtk/mtk-x11-errors.c b/mtk/mtk/mtk-x11-errors.c index 9b84a398f..fa9d8cc46 100644 --- a/mtk/mtk/mtk-x11-errors.c +++ b/mtk/mtk/mtk-x11-errors.c @@ -54,7 +54,8 @@ typedef int (* MtkXErrorHandler) (Display *, XErrorEvent *); static MtkXErrorHandler old_error_handler = NULL; /* number of times we've pushed the error handler */ static int error_handler_push_count = 0; -static GList *error_traps = NULL; +static GHashTable *display_error_traps = NULL; +static int init_count = 0; /* look up the extension name for a given major opcode. grubs around in * xlib to do it since a) it’s already cached there b) XQueryExtension @@ -84,6 +85,9 @@ display_error_event (Display *xdisplay, { GList *l; gboolean ignore = FALSE; + GList *error_traps; + + error_traps = g_hash_table_lookup (display_error_traps, xdisplay); for (l = error_traps; l; l = l->next) { @@ -172,11 +176,12 @@ error_handler_pop (void) static void delete_outdated_error_traps (Display *xdisplay) { - GList *l; + GList *l, *error_traps; unsigned long processed_sequence; processed_sequence = XLastKnownRequestProcessed (xdisplay); - l = error_traps; + l = error_traps = g_hash_table_lookup (display_error_traps, xdisplay); + g_hash_table_steal (display_error_traps, xdisplay); while (l != NULL) { @@ -196,6 +201,14 @@ delete_outdated_error_traps (Display *xdisplay) l = l->next; } } + + g_hash_table_insert (display_error_traps, xdisplay, error_traps); +} + +static void +free_trap_list (gpointer data) +{ + g_list_free_full (data, g_free); } /** @@ -204,7 +217,14 @@ delete_outdated_error_traps (Display *xdisplay) void mtk_x11_errors_init (void) { - XSetErrorHandler (mtk_x_error); + if (init_count == 0) + { + XSetErrorHandler (mtk_x_error); + display_error_traps = + g_hash_table_new_full (NULL, NULL, NULL, free_trap_list); + } + + init_count++; } /** @@ -213,8 +233,14 @@ mtk_x11_errors_init (void) void mtk_x11_errors_deinit (void) { - g_clear_list (&error_traps, g_free); - XSetErrorHandler (NULL); + init_count--; + g_assert (init_count >= 0); + + if (init_count == 0) + { + g_clear_pointer (&display_error_traps, g_hash_table_unref); + XSetErrorHandler (NULL); + } } /** @@ -224,6 +250,7 @@ void mtk_x11_error_trap_push (Display *xdisplay) { MtkErrorTrap *trap; + GList *error_traps; delete_outdated_error_traps (xdisplay); @@ -234,7 +261,10 @@ mtk_x11_error_trap_push (Display *xdisplay) trap->start_sequence = XNextRequest (xdisplay); trap->error_code = Success; + error_traps = g_hash_table_lookup (display_error_traps, xdisplay); + g_hash_table_steal (display_error_traps, xdisplay); error_traps = g_list_prepend (error_traps, trap); + g_hash_table_insert (display_error_traps, xdisplay, error_traps); } static int @@ -242,9 +272,11 @@ mtk_x11_error_trap_pop_internal (Display *xdisplay, gboolean need_code) { MtkErrorTrap *trap = NULL; - GList *l; + GList *l, *error_traps; int result; + error_traps = g_hash_table_lookup (display_error_traps, xdisplay); + g_return_val_if_fail (error_traps != NULL, Success); /* Find the first trap that hasn't been popped already */ diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index 2f97e33b9..16cab06d8 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -265,8 +265,6 @@ meta_x11_display_dispose (GObject *object) x11_display->xroot = None; } - meta_x11_display_destroy_error_traps (x11_display); - if (x11_display->xdisplay) { meta_x11_display_free_events (x11_display); @@ -288,6 +286,16 @@ meta_x11_display_dispose (GObject *object) G_OBJECT_CLASS (meta_x11_display_parent_class)->dispose (object); } +static void +meta_x11_display_finalize (GObject *object) +{ + MetaX11Display *x11_display = META_X11_DISPLAY (object); + + meta_x11_display_destroy_error_traps (x11_display); + + G_OBJECT_CLASS (meta_x11_display_parent_class)->finalize (object); +} + static void on_x11_display_opened (MetaX11Display *x11_display, MetaDisplay *display) @@ -302,6 +310,7 @@ meta_x11_display_class_init (MetaX11DisplayClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = meta_x11_display_dispose; + object_class->finalize = meta_x11_display_finalize; } static void