diff options
| author | Eli Zaretskii | 2017-10-04 10:27:49 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2017-10-04 10:27:49 +0300 |
| commit | ea39d470bf35e45f1d8e39795f06ac74b3c37fc7 (patch) | |
| tree | 406dbe320ffd5c9e2a31fd1b8568e119e50e9279 /src/keyboard.c | |
| parent | fdbaebde08f4e53e3fc06fae99398c68a4e285fb (diff) | |
| download | emacs-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.c | 14 |
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. */ |
| 146 | static Lisp_Object regular_top_level_message; | 146 | static Lisp_Object regular_top_level_message; |
| 147 | 147 | ||
| 148 | /* For longjmp to where kbd input is being done. */ | ||
| 149 | |||
| 150 | static 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 | ||
| 154 | static bool echoing; | 150 | static 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 |