master 9b66f875b36 1/2: Fix file-missing error during async native compilation (bug#81223)

Eli Zaretskii <[email protected]>
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: master
commit 9b66f875b3624918dcc20281a3632e758abfe4c3
Author: James Cherti <[email protected]>
Commit: Eli Zaretskii <[email protected]>

    Fix file-missing error during async native compilation (bug#81223)
    
    The async native compilation queue can sometimes retain stale jobs
    for files that no longer exist on disk (for example, when files are
    removed during a package upgrade or deletion).  Attempting to resolve
    the target .eln filename for these missing files signals a
    file-missing error.
    * lisp/emacs-lisp/comp-run.el (comp--run-async-workers): Verify
    source files exist before attempting to resolve their .eln paths in
    the dispatch loop.  In the process sentinel, wrap the compilation
    block in a condition-case to catch file-missing errors and prevent
    the async worker queue from stalling.
---
 lisp/emacs-lisp/comp-run.el | 48 ++++++++++++++++++++++++++++++---------------
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/lisp/emacs-lisp/comp-run.el b/lisp/emacs-lisp/comp-run.el
index 64e20327906..203b8531172 100644
--- a/lisp/emacs-lisp/comp-run.el
+++ b/lisp/emacs-lisp/comp-run.el
@@ -279,14 +279,21 @@ display a message."
          do (cl-assert (string-match-p comp-valid-source-re source-file) nil
                        "`comp-files-queue' should be \".el\" files: %s"
                        source-file)
-         when (or native-comp-always-compile
-                  load ; Always compile when the compilation is
-                       ; commanded for late load.
-                  ;; Skip compilation if `comp-el-to-eln-filename' fails
-                  ;; to find a writable directory.
-                  (with-demoted-errors "Async compilation :%S"
-                    (file-newer-than-file-p
-                     source-file (comp-el-to-eln-filename source-file))))
+         when (and
+               ;; Verify that the source file still exists on disk
+               ;; as a regular file before calling
+               ;; `comp-el-to-eln-filename'. This check prevents
+               ;; `file-missing' errors caused by stale jobs in the
+               ;; async compilation queue.
+               (file-regular-p source-file)
+               (or native-comp-always-compile
+                   load ; Always compile when the compilation is
+                        ; commanded for late load.
+                   ;; Skip compilation if `comp-el-to-eln-filename' fails
+                   ;; to find a writable directory.
+                   (with-demoted-errors "Async compilation :%S"
+                     (file-newer-than-file-p
+                      source-file (comp-el-to-eln-filename source-file)))))
          do (let* ((expr `((require 'comp)
                            (setq comp-async-compilation t
                                  warning-fill-column most-positive-fixnum)
@@ -362,14 +369,23 @@ display a message."
                                 source-file)
                                (comp--accept-and-process-async-output process)
                                (ignore-errors (delete-file temp-file))
-                               (let ((eln-file (comp-el-to-eln-filename
-                                                source-file1)))
-                                 (when (and load1
-                                            (zerop (process-exit-status
-                                                    process))
-                                            (file-exists-p eln-file))
-                                   (native-elisp-load eln-file
-                                                      (eq load1 'late))))
+                               ;; Catch the file-missing error that
+                               ;; occurs if the original source file is
+                               ;; deleted while the asynchronous worker
+                               ;; is compiling it. Handling this error
+                               ;; prevents the sentinel from aborting
+                               ;; and ensures the compilation queue
+                               ;; continues processing.
+                               (condition-case nil
+                                   (let ((eln-file (comp-el-to-eln-filename
+                                                    source-file1)))
+                                     (when (and load1
+                                                (zerop (process-exit-status
+                                                        process))
+                                                (file-exists-p eln-file))
+                                       (native-elisp-load eln-file
+                                                          (eq load1 'late))))
+                                 (file-missing nil))
                                (comp--run-async-workers))
                              :noquery (not native-comp-async-query-on-exit))))
               (set-process-thread process nil)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.