Subject: bug#25172: 26.0.50; Concurrency feature, sit-for doesn't work (crashing and unexpected behaviour)

From: Eli Zaretskii <[email-masked]>
Date: Mon, 12 Dec 2016 19:37:19 +0200

> From: Elias Mårtenson <[email-masked]>
> Date: Mon, 12 Dec 2016 12:50:24 +0800
> Cc: Eli Zaretskii <[email-masked]>, [email-masked]
> 
> I tried with the latest version (a92a027d58cb4df5bb6c7e3c546a72183a192f45)
> and I'm still getting the same error.
> 
> The stack trace is as follows:
> [...]
> #34 0x0000000000578a22 in emacs_abort () at sysdep.c:2342
> #35 0x0000000000564247 in unblock_input_to (level=-1) at keyboard.c:7167
> #36 0x000000000056425e in unblock_input () at keyboard.c:7183
> #37 0x000000000069c5e4 in xg_select (fds_lim=15, rfds=0x7fffe59e19a0,
> wfds=0x7fffe59e1920, efds=0x0, timeout=0x7fffe59e1900, sigmask=0x0) at
> xgselect.c:162

xg_select uses block_input/unblock_input, something other *select
implementations used by Emacs don't do (as those others are system
APIs).  block_input/unblock_input manipulate a global variable that is
not incremented and decremented atomically, so it's fundamentally
thread-unsafe.  Moreover, some places in Emacs reset that global
variable to zero (although I don't believe those places are part of
your scenario).

The above is especially important because the calls to the *select
functions are about the only place in Emacs where several threads can
run in parallel, because they are called by thread_select like this:

  release_global_lock ();
  sa->result = (sa->func) (sa->max_fds, sa->rfds, sa->wfds, sa->efds,
			   sa->timeout, sa->sigmask);
  acquire_global_lock (self);

So between the call to release_global_lock, which allows another
thread to grab the lock, and the subsequent call to
acquire_global_lock several threads could run and more or less
simultaneously call the *select function.  If that function is
xg_select, these threads might step on each other's toes by calling
block_input/unblock_input in parallel.  This could easily cause the
global variable to become negative, which then causes the above abort.

Long story short, could you please try removing the calls to
block_input/unblock_input from xgselect.c, and see if that solves
these crashes?  (These calls were introduced to fix a rare and elusive
bug, but I don't think you will see that bug unless you do what that
bug's recipe calls for.  And anyway, this removal is just so we see
whether this is indeed the reason for the problem, I don't really
suggest to remove them for good.)

Thanks.