bug#81223: [PATCH] Fix file-missing error during async native compilation

Philip Kaludercic <[email protected]>
Newsgroups gmane.emacs.bugs
Message-ID <[email protected]>
James Cherti <[email protected]> writes:

> Hello Andrea,
>
> It makes sense. I've updated the patch:
>
> Attached: 0001-V2-Fix-file-missing-error-during-async-native-compilati.patch
>
> On 2026-07-27 11:21, Andrea Corallo wrote:
>> James Cherti <[email protected]> writes:
>> 
>>> On 2026-06-11 11:07, Sean Whitton wrote:
>>>> James Cherti [11/Jun  9:41am -04] wrote:
>>>>>   From a8f13a55a4838a0d2ead62513c7d1a9616c1b501 Mon Sep 17 00:00:00 2001
>>>>> From: James Cherti <[email protected]>
>>>>> Date: Thu, 11 Jun 2026 09:29:39 -0400
>>>>> Subject: [PATCH] Fix file-missing error during async native compilation
>>>>>
>>>>> When a package is upgraded or deleted, the async compilation queue can
>>>>> retain stale jobs for files that no longer exist on disk.  Attempting to
>>>>> resolve the target .eln filename for these missing files signals a
>>>>> file-missing error that disrupts the queue.
>>>>>
>>>>> * lisp/emacs-lisp/comp-run.el (comp--run-async-workers): Verify source
>>>>> files exist before attempting to resolve their .eln paths in both the
>>>>> dispatch loop and the process sentinel.
>>>>
>>>> Shorten these remarks and add corresponding code comments, please.
>>>>
>>>> Adding Philip for review since it seems primarily a package.el issue.
>>>
>>> You can find attached v2 of the patch
>>> (0001-V2-Fix-file-missing-error-during-async-native-compilati.patch).
>>>
>>> Changes since the previous version:
>>> - Added explanatory comments regarding the file existence checks.
>>>
>>> For context, I want to clarify that this fix is not specifically tied
>>> to package management operations. It resolves a broader issue by
>>> handling any stale jobs in the async native compilation queue where
>>> the target files no longer exist on disk.
>>>
>>> --
>>> James Cherti
>> Hi James,
>> Thanks for the patch. Couple of points:
>> 
>>> GitHub: https://github.com/jamescherti
>>> Website: https://www.jamescherti.com/
>>>
>>>  From 55ba77809cb1d371f79eb4e59df8db819e100456 Mon Sep 17 00:00:00 2001
>>> From: James Cherti <[email protected]>
>>> Date: Fri, 12 Jun 2026 06:07:23 -0400
>>> Subject: [PATCH] Fix file-missing error during async native compilation
>>>
>>> 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 both the
>>> dispatch loop and the process sentinel.
>>> ---
>>>   lisp/emacs-lisp/comp-run.el | 23 ++++++++++++++++++-----
>>>   1 file changed, 18 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/lisp/emacs-lisp/comp-run.el b/lisp/emacs-lisp/comp-run.el
>>> index 64e20327906..c70c5b0a512 100644
>>> --- a/lisp/emacs-lisp/comp-run.el
>>> +++ b/lisp/emacs-lisp/comp-run.el
>>> @@ -282,13 +282,20 @@ comp--run-async-workers
>>>            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))))
>>> +                  (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)
>>> +                   (with-demoted-errors "Async compilation :%S"
>>> +                     (file-newer-than-file-p
>>> +                      source-file (comp-el-to-eln-filename source-file)))))
>> The file-regular-p check in the dispatch loop is currently bypassed
>> when
>> either native-comp-always-compile or load is non-nil. Thus, stale jobs
>> in those modes still start a worker. Should the check wrap the entire or
>> condition?
>>> Also, the sentinel still has a check-then-use race: the source can
>> disappear between file-regular-p and comp-el-to-eln-filename, causing
>> the sentinel to signal before restarting the queue.
>> I'm wondering, wouldn't maybe be safer to handle file-missing around
>> comp-el-to-eln-filename directly and ensure comp--run-async-workers is
>> always called? > Thanks
>>    Andrea
>> 
>
>
> --
> James Cherti
> GitHub: https://github.com/jamescherti
> Website: https://www.jamescherti.com/
>
> From fba7bda59f0dd19ae031681fafb8f64e5d8b4bcc Mon Sep 17 00:00:00 2001
> From: James Cherti <[email protected]>
> Date: Wed, 29 Jul 2026 11:13:12 -0400
> Subject: [PATCH] Fix file-missing error during async native compilation
>
> 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.

Unrelated to the contents of this patch: You should mention the bug
number ("(bug#81223)")in the commit message, see the CONTRIBUTE file.

> ---
>  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
> @@ -277,18 +277,25 @@ comp--run-async-workers
>           for (source-file . load) = (pop comp-files-queue)
>           while source-file
>           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)
>                             ,(let ((set (list 'setq)))
>                                (dolist (var '(comp-file-preloaded-p
> @@ -360,18 +367,27 @@ comp--run-async-workers
>                                 (run-hook-with-args
>                                  'native-comp-async-cu-done-functions
>                                  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)
>                (puthash source-file process comp-async-compilations))
>           when (>= (comp--async-runnings) (comp--effective-async-max-jobs))
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.