From: Eli Zaretskii Date: Sat, 16 Oct 2021 11:47:32 +0000 (+0300) Subject: Avoid aborts when a thread is signaled while "waiting for input". X-Git-Tag: emacs-28.0.90~277 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e8488808dfe1460ce07042a1a523097ab90cf079;p=emacs.git Avoid aborts when a thread is signaled while "waiting for input". * src/process.c (kbd_is_ours): New function. (wait_reading_process_output): Set 'waiting_for_input' only if the current thread is monitoring the keyboard descriptor. See also https://lists.gnu.org/archive/html/emacs-devel/2021-10/msg01180.html. (Bug#51229) --- diff --git a/src/process.c b/src/process.c index 746cdc0428a..6731f8808f5 100644 --- a/src/process.c +++ b/src/process.c @@ -683,6 +683,22 @@ clear_waiting_thread_info (void) } } +/* Return TRUE if the keyboard descriptor is being monitored by the + current thread, FALSE otherwise. */ +static bool +kbd_is_ours (void) +{ + for (int fd = 0; fd <= max_desc; ++fd) + { + if (fd_callback_info[fd].waiting_thread != current_thread) + continue; + if ((fd_callback_info[fd].flags & (FOR_READ | KEYBOARD_FD)) + == (FOR_READ | KEYBOARD_FD)) + return true; + } + return false; +} + /* Compute the Lisp form of the process status, p->status, from the numeric status that was returned by `wait'. */ @@ -5312,13 +5328,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, wait_reading_process_output_1 (); } - /* Cause C-g and alarm signals to take immediate action, + /* Cause C-g signals to take immediate action, and cause input available signals to zero out timeout. It is important that we do this before checking for process activity. If we get a SIGCHLD after the explicit checks for process activity, timeout is the only way we will know. */ - if (read_kbd < 0) + if (read_kbd < 0 && kbd_is_ours ()) set_waiting_for_input (&timeout); /* If status of something has changed, and no input is @@ -5448,7 +5464,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, { clear_waiting_for_input (); redisplay_preserve_echo_area (11); - if (read_kbd < 0) + if (read_kbd < 0 && kbd_is_ours ()) set_waiting_for_input (&timeout); }