aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Porter2023-09-18 10:17:12 -0700
committerJim Porter2023-09-18 10:26:34 -0700
commit146bd41ddef21a19634e2b90db4bfb619a2091b2 (patch)
tree6eba4aedaa2d5557073adb8243fd6e1751ea6aea
parent991bf3f0f5dff66794785ebfcc867611fe75e0da (diff)
downloademacs-146bd41ddef21a19634e2b90db4bfb619a2091b2.tar.gz
emacs-146bd41ddef21a19634e2b90db4bfb619a2091b2.zip
Fix another race condition when waiting for Eshell processes
When checking if the other processes in our pipeline are "alive", we also need to check whether their sentinels are finished. Otherwise, we might proceed with command evaluation while one of the other processes is still cleaning up. * lisp/eshell/esh-proc.el (eshell-process-active-p): New function... (eshell-wait-for-process) * lisp/eshell/esh-cmd.el (eshell-resume-command): ... use it.
-rw-r--r--lisp/eshell/esh-cmd.el2
-rw-r--r--lisp/eshell/esh-proc.el16
2 files changed, 12 insertions, 6 deletions
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 0d73b2d6e69..af50a485226 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -1018,7 +1018,7 @@ process(es) in a cons cell like:
1018 ;; Make sure PROC is one of our foreground processes and 1018 ;; Make sure PROC is one of our foreground processes and
1019 ;; that all of those processes are now dead. 1019 ;; that all of those processes are now dead.
1020 (member proc eshell-last-async-procs) 1020 (member proc eshell-last-async-procs)
1021 (not (seq-some #'process-live-p eshell-last-async-procs))) 1021 (not (seq-some #'eshell-process-active-p eshell-last-async-procs)))
1022 (eshell-resume-eval))) 1022 (eshell-resume-eval)))
1023 1023
1024(defun eshell-resume-eval () 1024(defun eshell-resume-eval ()
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index aed8f8af93d..e564c755320 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -157,15 +157,21 @@ The signals which will cause this to happen are matched by
157 (declare-function eshell-reset "esh-mode" (&optional no-hooks)) 157 (declare-function eshell-reset "esh-mode" (&optional no-hooks))
158 (eshell-reset))) 158 (eshell-reset)))
159 159
160(defun eshell-process-active-p (process)
161 "Return non-nil if PROCESS is active.
162This is like `process-live-p', but additionally checks whether
163`eshell-sentinel' has finished all of its work yet."
164 (or (process-live-p process)
165 ;; If we have handles, this is an Eshell-managed
166 ;; process. Wait until we're 100% done and have
167 ;; cleared out the handles (see `eshell-sentinel').
168 (process-get process :eshell-handles)))
169
160(defun eshell-wait-for-process (&rest procs) 170(defun eshell-wait-for-process (&rest procs)
161 "Wait until PROCS have successfully completed." 171 "Wait until PROCS have successfully completed."
162 (dolist (proc procs) 172 (dolist (proc procs)
163 (when (eshell-processp proc) 173 (when (eshell-processp proc)
164 (while (or (process-live-p proc) 174 (while (eshell-process-active-p proc)
165 ;; If we have handles, this is an Eshell-managed
166 ;; process. Wait until we're 100% done and have
167 ;; cleared out the handles (see `eshell-sentinel').
168 (process-get proc :eshell-handles))
169 (when (input-pending-p) 175 (when (input-pending-p)
170 (discard-input)) 176 (discard-input))
171 (sit-for eshell-process-wait-seconds 177 (sit-for eshell-process-wait-seconds