Subject: Re: bug#28630: 27.0.50; C-g while a non-main thread is sitting crashes Emacs

From: Eli Zaretskii <[email-masked]>
Date: Wed, 04 Oct 2017 11:14:26 +0300

> Date: Wed, 04 Oct 2017 16:39:27 +0900
> From: YAMAMOTO Mitsuharu <[email-masked]>
> Cc: 	[email-masked],
> 	[email-masked],
> 	[email-masked]
> 
> >>>>> On Mon, 02 Oct 2017 19:08:59 +0300, Eli Zaretskii <[email-masked]> said:
> 
> > I think the second thread calls setjmp and clobbers the values set
> > by the main thread, when the main thread called setjmp.  We need to
> > eliminate this possibility of threads stepping on each other's toes.
> 
> Make the global variable `getcjmp' thread-local?

That indeed was the central part of the solution I installed.  But it
isn't enough, because in a TTY session C-g triggers a SIGINT, which is
delivered to the main thread.  So we need also to make sure that when
the signal handler calls quit_throw_to_read_char, current_thread
points to main_thread, we have the global lock held by the main
thread, and all our Lisp thread machinery is aware that it's the main
thread that's running.  Otherwise, we are asking for trouble.

Note that this means the effect of C-g while I/O APIs are called from
non-main threads is inherently unportable: the effect will be
different in TTY and GUI sessions on Unix, and also on Windows (where
there are no signals, and therefore the original recipe didn't crash
at all, but instead interrupted the sit-for on the non-main thread and
caused that thread's early demise).

After the change, sit-for on non-main thread is effectively a
sleep-for, at least on Unix TTY frames (and I think on GUI frames as
well).  But on MS-Windows and I think also NS it still works as
sit-for on the non-main thread.

Thanks.