diff options
author | Eli Zaretskii <eliz@gnu.org> | 2017-10-04 10:27:49 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2017-10-04 10:27:49 +0300 |
commit | ea39d470bf35e45f1d8e39795f06ac74b3c37fc7 (patch) | |
tree | 406dbe320ffd5c9e2a31fd1b8568e119e50e9279 /src/thread.c | |
parent | fdbaebde08f4e53e3fc06fae99398c68a4e285fb (diff) | |
download | emacs-ea39d470bf35e45f1d8e39795f06ac74b3c37fc7.tar.gz |
Avoid crashes on C-g when several threads wait for input
* src/thread.h (m_getcjmp): New member of 'struct thread_state'.
(getcjmp): Define to current thread's 'm_getcjmp'.
* src/thread.c (maybe_reacquire_global_lock): Switch to main
thread, since this is called from a SIGINT handler, which always
runs in the context of the main thread.
* src/lisp.h (sys_jmp_buf, sys_setjmp, sys_longjmp): Move the
definitions before thread.h is included, as thread.h now uses
sys_jmp_buf.
* src/keyboard.c (getcjmp): Remove declaration.
(read_char): Don't call maybe_reacquire_global_lock here.
(handle_interrupt): Call maybe_reacquire_global_lock here, if
invoked from the SIGINT handler, to make sure
quit_throw_to_read_char runs with main thread's Lisp bindings and
uses the main thread's jmp_buf buffer. (Bug#28630)
Diffstat (limited to 'src/thread.c')
-rw-r--r-- | src/thread.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/thread.c b/src/thread.c index 42d7791ad0f..d075bdb3a13 100644 --- a/src/thread.c +++ b/src/thread.c @@ -101,14 +101,20 @@ acquire_global_lock (struct thread_state *self) post_acquire_global_lock (self); } -/* This is called from keyboard.c when it detects that SIGINT - interrupted thread_select before the current thread could acquire - the lock. We must acquire the lock to prevent a thread from - running without holding the global lock, and to avoid repeated - calls to sys_mutex_unlock, which invokes undefined behavior. */ +/* This is called from keyboard.c when it detects that SIGINT was + delivered to the main thread and interrupted thread_select before + the main thread could acquire the lock. We must acquire the lock + to prevent a thread from running without holding the global lock, + and to avoid repeated calls to sys_mutex_unlock, which invokes + undefined behavior. */ void maybe_reacquire_global_lock (void) { + /* SIGINT handler is always run on the main thread, see + deliver_process_signal, so reflect that in our thread-tracking + variables. */ + current_thread = &main_thread; + if (current_thread->not_holding_lock) { struct thread_state *self = current_thread; |