Subject: Re: bug#25247: 26.0.50; Concurrency crashes with XLib

From: Ken Raeburn <[email-masked]>
Date: Fri, 30 Dec 2016 02:19:29 -0500

I’m still looking through yesterday’s set of stack traces, but in my experimenting I was able to reproduce some crashes once I noticed my build had automatically configured itself for the Lucid toolkit when I didn’t have GTK installed.  I fixed that, and got crashes fairly often with Tino’s recipe.

In the cases I’ve hit, it appears that Xlib is getting called via Glib callbacks with lots of GTK, GDK, and Cairo library frames on the stack, in one of the threads calling xg_select, and in the main thread, redisplay is calling into Xlib (e.g., XSetClipRectangles) to draw text on the screen.  If I add a call to XInitThreads, the crashes stop.  However, it may not be enough — Tino’s basic test works, but if I resize the window Emacs may stop responding to X input, for reasons I haven’t tracked down yet.

Tino, could you please try the patch below and see if it fixes some of the crashes you’re seeing?

As for Eli’s comments about moving the locking code into xgselect.c, I think that’s going to be needed.  I’ve got a patch in my private repository from a while back, waiting for some cleanup, that started doing something like that, but didn’t cover the Mac ns_select version because I’m unfamiliar with that code.  The unblock_input code accesses global variables like interrupt_input_blocked and pending_signals, but it can be called from xg_select without holding the global lock.  I think I also hit a case where current_thread was null due to the exiting of the “current” Lisp thread, and something called via unblock_input tried to use it to access one of the now-per-Lisp-thread variables.

Ken

commit e333e1ab48a0c938aba18ec22b3d94273078a982
Author: Ken Raeburn <[email-masked]>
Date:   Thu Dec 29 20:56:31 2016 -0500

    Initialize thread support for Xlib.
    
    * src/xterm.c (x_initialize) [THREADS_ENABLED]: Call XInitThreads
    before doing anything else with X.

diff --git a/src/xterm.c b/src/xterm.c
index bdc21e6de0..6f79a7d094 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -12762,6 +12762,13 @@ x_initialize (void)
   /* Try to use interrupt input; if we can't, then start polling.  */
   Fset_input_interrupt_mode (Qt);
 
+#ifdef THREADS_ENABLED
+  /* This must be called before any other Xlib routines.  */
+  if (XInitThreads () == 0)
+    fprintf (stderr,
+            "Warning: An error occurred initializing X11 thread support!\n");
+#endif
+
 #ifdef USE_X_TOOLKIT
   XtToolkitInitialize ();