emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: long-standing GTK bug


From: Adam Sjøgren
Subject: Re: long-standing GTK bug
Date: Sun, 17 May 2020 13:40:38 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

I wrote:

> If you remove the workaround in frame.c and remove the call to
> emacs_abort() when using GTK in x_connection_closed() in xterm.c, and
> the connection to a display is terminated while Emacs has a window on
> that display, you'll still get an endless stream of warnings from GLib,
> i.e. "the GTK bug".

I have been looking further into it, and I think I now understand what
happens.

Emacs calls gtk_events_pending(), which then continues to
g_main_context_prepare(), in which a counter in the context structure,
in_check_or_prepare, is incremented to detect recursive calls to this
function in GLib.

Before the counter is decremented again, the X-connection disappears,
and X calls Emacs' error handler x_io_error_quitter().

The error handler closes the display¹, and Emacs then continues. But it
doesn't return to the place in g_main_context_prepare(), so the counter
isn't decremented.

When Emacs then calls gtk_events_pending() again, GLib looks at the
counter, and emits warnings about recursive calls.

At least that is what I think is happening - gleaned from adding a
breakpoint to delete_frame() and staring at this backtrace and the code
in GLib²:

  #0  delete_frame (frame=0x555556183ba5, force=force@entry=0xa170) at 
frame.c:1902
  #1  0x000055555559707e in x_connection_closed (dpy=dpy@entry=0x555556c58590, 
error_message=<optimized out>, 
      error_message@entry=0x7fffffffcf40 "Connection lost to X server 
'localhost:10.0'", ioerror=ioerror@entry=true) at lisp.h:1042
  #2  0x00005555555971a9 in x_io_error_quitter (display=0x555556c58590) at 
xterm.c:10180
  #3  0x00007ffff6aac20e in _XIOError () at /lib/x86_64-linux-gnu/libX11.so.6
  #4  0x00007ffff6aa9985 in _XEventsQueued () at 
/lib/x86_64-linux-gnu/libX11.so.6
  #5  0x00007ffff6a9b511 in XPending () at /lib/x86_64-linux-gnu/libX11.so.6
  #6  0x00007ffff7435b6f in  () at /lib/x86_64-linux-gnu/libgdk-3.so.0
  #7  0x00007ffff6e1fd7f in g_main_context_prepare () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
  #8  0x00007ffff6e2072b in  () at /lib/x86_64-linux-gnu/libglib-2.0.so.0
  #9  0x00007ffff6e208c8 in g_main_context_pending () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
  #10 0x00007ffff7708f0e in gtk_events_pending () at 
/lib/x86_64-linux-gnu/libgtk-3.so.0
  #11 0x000055555564c97d in XTread_socket (terminal=<optimized out>, 
hold_quit=0x7fffffffd200) at xterm.c:9398

To test my interpretation, I decided to decrement the counter in the
context structure from inside x_connection_closed(), by adding:

        GMainContext *context;
        context = g_main_context_default();
        // Try resetting recursion prevention counter:
        context->in_check_or_prepare = 0;

before calling gdk_display_close() on the display that has disappeared³.

This makes the endless stream of warnings not appear!

However, my quick test required me to copy the struct _GMainContext
definition from glib/gmain.c into xterm.c, which is not the correct way
to go about this, I'm sure.

I do feel that this is progress, though. Now we just need to figure out
the right way to handle it.

If that is for gdk_display_close() to reset the in_check_or_prepare
counter, or if it is something that can be changed in Emacs, I don't
know.

I have updated the current GTK issue⁴ with my observations, but I'm
hoping for some input from emacs-devel as well.


  Best regards,

    Adam


¹ If you change it from calling emacs_abort() to close the display, as I
  have, that is.

² https://github.com/GNOME/glib/blob/mainline/glib/gmain.c#L3530

³ 
https://koldfront.dk/git/emacs/commit/?h=scratch/gtk-x-disconnect&id=94eea826b6aa69ecf94301b4da251059dc89212bhttps://gitlab.gnome.org/GNOME/gtk/-/issues/2315

-- 
 "When you grow up, it's not allowed."                      Adam Sjøgren
 "All the more reason I should do it *now*!"           address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]