Subject: bug#79334: [PATCH] Don't release thread select lock unnecessarily

From: Spencer Baugh <[email-masked]>
Date: Thu, 28 Aug 2025 17:08:43 -0400

Tags: patch

Previously, we were using thread_select to release the thread
lock around two different calls to select in
wait_reading_process_output.  The main call to select was fine,
but we also used thread_select for a pselect call which returns
immediately (with a timeout of 0) and is supposed to just check
if any file descriptors are active.

If we actually thread switch at that pselect, it's likely to
break internal state for Emacs: namely, the call to
status_notify immediately after can close file descriptors which
another thread is selecting on, causing that thread to get EBADF
from select and then call emacs_abort.

We don't need to thread switch here, so don't.

* src/process.c (wait_reading_process_output): Remove
unnecessary thread_select wrapper.

In GNU Emacs 30.1.90 (build 29, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.15.12, Xaw scroll bars) of 2025-08-26 built on
 igm-qws-u22796a
Repository revision: 54857fe2fb0ed033afcba231f920f8f7fa185333
Repository branch: emacs-30
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Rocky Linux 8.10 (Green Obsidian)

Configured using:
 'configure --with-x-toolkit=lucid --without-gpm --without-gconf
 --without-selinux --without-imagemagick --with-modules --with-gif=no
 --with-cairo --with-rsvg --without-compress-install --with-tree-sitter
 --with-native-compilation=aot
 PKG_CONFIG_PATH=/usr/local/home/garnish/libtree-sitter/0.22.6-1/lib/pkgconfig/'

>From 68e7ed37036498a0df0232196c50cced38cdb751 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <[email-masked]>
Date: Thu, 28 Aug 2025 17:06:56 -0400
Subject: [PATCH] Don't release thread select lock unnecessarily

Previously, we were using thread_select to release the thread
lock around two different calls to select in
wait_reading_process_output.  The main call to select was fine,
but we also used thread_select for a pselect call which returns
immediately (with a timeout of 0) and is supposed to just check
if any file descriptors are active.

If we actually thread switch at that pselect, it's likely to
break internal state for Emacs: namely, the call to
status_notify immediately after can close file descriptors which
another thread is selecting on, causing that thread to get EBADF
from select and then call emacs_abort.

We don't need to thread switch here, so don't.

* src/process.c (wait_reading_process_output): Remove
unnecessary thread_select wrapper.
---
 src/process.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/process.c b/src/process.c
index c8b70a4174c..b33bebb9a35 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5513,11 +5513,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
 	  if (0 <= fd)
 	    FD_CLR (fd, &Atemp);
 
+	  /* We're just checking to see if any of these fds are active,
+	     so make pselect return immediately. */
 	  timeout = make_timespec (0, 0);
-	  if ((thread_select (pselect, max_desc + 1,
-			      &Atemp,
-			      (num_pending_connects > 0 ? &Ctemp : NULL),
-			      NULL, &timeout, NULL)
+	  if ((pselect (max_desc + 1,
+			&Atemp,
+			(num_pending_connects > 0 ? &Ctemp : NULL),
+			NULL, &timeout, NULL)
 	       <= 0))
 	    {
 	      /* It's okay for us to do this and then continue with
-- 
2.43.7