* bug#68792: Process sentinels are sometimes not called when inotify is used
@ 2024-01-29 5:15 Bryan Joseph Tabor
0 siblings, 0 replies; only message in thread
From: Bryan Joseph Tabor @ 2024-01-29 5:15 UTC (permalink / raw)
To: 68792
[-- Attachment #1.1: Type: text/plain, Size: 4035 bytes --]
Tags: patch
Hi, to reproduce this issue please save the following elisp to proc.el:
(defvar p-stopped nil)
(defun my-sentinel (proc str)
(when (string-match "^\\(?:finished\n\\|exited abnormally\\|killed\n\\)"
str)
(setq p-stopped t)))
(defun wait-for-process-end (proc)
(while (not p-stopped)
(message "process status is: %s" (process-status proc))
(accept-process-output proc 0.1 nil t)))
(defun f ()
(with-temp-buffer
(inotify-add-watch "foo.txt" t #'ignore)
(let ((proc (start-process "p" (current-buffer) "bash" "-c" "touch foo.txt")))
(setq p-stopped nil)
(set-process-sentinel proc 'my-sentinel)
(wait-for-process-end proc))))
Please also create a file 'foo.txt'
$ touch foo.txt
Now, invoke the following command
$ emacs -Q --script proc.el --eval "(f)"
This command will never exit, and print "process status is: exit" forever.
The expected behavior is that, because process "p" is exited, its sentinel should be called, so 'wait-for-process-end' will complete and Emacs will exit.
After some investigation, I found that 'wait_reading_process_output' in process.c never calls the sentinel for the process because the pselect invocation in this code (src/process.c) always returns nonzero:
if ((thread_select (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
the loop, since timeout has already been zeroed out. */
clear_waiting_for_input ();
got_some_output = status_notify (NULL, wait_proc);
if (do_display) redisplay_preserve_echo_area (13);
}
This pselect invocation always returns nonzero because the inotify fd for "foo.txt" is included in the pselect readfds and is readable. However, the inotify fd is never handled within 'wait_reading_process_output'.
If I understand this code correctly, the intent here is to prioritize handling ready fds before calling 'status_notify', which invokes sentinels. However, it seems inotify fds are not handled in 'wait_reading_process_output', so there is no reason to care about inotify fds here. I believe the correct fix is to filter for process fds in this pselect call. To accomplish this, the included patch filters for process fds in 'compute_input_wait_mask'. It appears to me that all usage of 'compute_input_wait_mask' only cares about process fds, so I believe this is a safe change.
In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.38, cairo version 1.17.8) of 2023-12-23 built on ostrich
Repository revision: 5c3ff1494b69bf45b99125f2423174222badfa43
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12101011
System Description: Arch Linux
Configured using:
'configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib
--localstatedir=/var --mandir=/usr/share/man --with-gameuser=:games
--with-modules --without-m17n-flt --without-gconf
--with-native-compilation=yes --with-xinput2 --with-x-toolkit=gtk3
--without-xaw3d --with-sound=no --with-tree-sitter --without-gpm
--without-compress-install
'--program-transform-name=s/\([ec]tags\)/\1.emacs/'
'CFLAGS=-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions
-Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security
-fstack-clash-protection -fcf-protection'
LDFLAGS=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now'
[-- Attachment #1.2: Type: text/html, Size: 17866 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-process.c-Fix-process-sentinels-not-called-when-inot.patch --]
[-- Type: text/x-patch; name="0001-process.c-Fix-process-sentinels-not-called-when-inot.patch", Size: 867 bytes --]
From 281f2a2da9b5ce7cc9c9029be99801e923dcbf24 Mon Sep 17 00:00:00 2001
From: Bryan Tabor <bjt84@cornell.edu>
Date: Sun, 28 Jan 2024 23:36:04 -0500
Subject: [PATCH] * process.c: Fix process sentinels not called when inotify
used
---
src/process.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/process.c b/src/process.c
index ddab9ed6c01..41cc8a0caa5 100644
--- a/src/process.c
+++ b/src/process.c
@@ -597,7 +597,8 @@ compute_input_wait_mask (fd_set *mask)
if (fd_callback_info[fd].waiting_thread != NULL
&& fd_callback_info[fd].waiting_thread != current_thread)
continue;
- if ((fd_callback_info[fd].flags & FOR_READ) != 0)
+ if ((fd_callback_info[fd].flags & (FOR_READ | PROCESS_FD))
+ == (FOR_READ | PROCESS_FD))
{
FD_SET (fd, mask);
fd_callback_info[fd].waiting_thread = current_thread;
--
2.43.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2024-01-29 5:15 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-29 5:15 bug#68792: Process sentinels are sometimes not called when inotify is used Bryan Joseph Tabor
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.