aboutsummaryrefslogtreecommitdiffstats
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorEli Zaretskii2017-10-04 10:27:49 +0300
committerEli Zaretskii2017-10-04 10:27:49 +0300
commitea39d470bf35e45f1d8e39795f06ac74b3c37fc7 (patch)
tree406dbe320ffd5c9e2a31fd1b8568e119e50e9279 /src/keyboard.c
parentfdbaebde08f4e53e3fc06fae99398c68a4e285fb (diff)
downloademacs-ea39d470bf35e45f1d8e39795f06ac74b3c37fc7.tar.gz
emacs-ea39d470bf35e45f1d8e39795f06ac74b3c37fc7.zip
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/keyboard.c')
-rw-r--r--src/keyboard.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index e8701b88708..ee353d2b078 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -145,10 +145,6 @@ static Lisp_Object recover_top_level_message;
145/* Message normally displayed by Vtop_level. */ 145/* Message normally displayed by Vtop_level. */
146static Lisp_Object regular_top_level_message; 146static Lisp_Object regular_top_level_message;
147 147
148/* For longjmp to where kbd input is being done. */
149
150static sys_jmp_buf getcjmp;
151
152/* True while displaying for echoing. Delays C-g throwing. */ 148/* True while displaying for echoing. Delays C-g throwing. */
153 149
154static bool echoing; 150static bool echoing;
@@ -2570,9 +2566,6 @@ read_char (int commandflag, Lisp_Object map,
2570 so restore it now. */ 2566 so restore it now. */
2571 restore_getcjmp (save_jump); 2567 restore_getcjmp (save_jump);
2572 pthread_sigmask (SIG_SETMASK, &empty_mask, 0); 2568 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
2573#if THREADS_ENABLED
2574 maybe_reacquire_global_lock ();
2575#endif
2576 unbind_to (jmpcount, Qnil); 2569 unbind_to (jmpcount, Qnil);
2577 XSETINT (c, quit_char); 2570 XSETINT (c, quit_char);
2578 internal_last_event_frame = selected_frame; 2571 internal_last_event_frame = selected_frame;
@@ -10508,6 +10501,13 @@ handle_interrupt (bool in_signal_handler)
10508 outside of polling since we don't get SIGIO like X and we don't have a 10501 outside of polling since we don't get SIGIO like X and we don't have a
10509 separate event loop thread like W32. */ 10502 separate event loop thread like W32. */
10510#ifndef HAVE_NS 10503#ifndef HAVE_NS
10504#ifdef THREADS_ENABLED
10505 /* If we were called from a signal handler, we must be in the main
10506 thread, see deliver_process_signal. So we must make sure the
10507 main thread holds the global lock. */
10508 if (in_signal_handler)
10509 maybe_reacquire_global_lock ();
10510#endif
10511 if (waiting_for_input && !echoing) 10511 if (waiting_for_input && !echoing)
10512 quit_throw_to_read_char (in_signal_handler); 10512 quit_throw_to_read_char (in_signal_handler);
10513#endif 10513#endif