Rework eln deletion strategy for new eln-cache folder structure
When recompiling remove the corresponding stale elns found in the `comp-eln-load-path'. When removing a package remove the corresponding elns too. On Windows both of these are performed only when possible, when it's not the file is renamed as .eln.old and a last attempt to remove this is performed closing the Emacs session. When a file being deleted was loaded by multiple Emacs sessions the last one being closed should delete it. * lisp/emacs-lisp/comp.el (comp-clean-up-stale-eln): New function. (comp-delete-or-replace-file): Rename from `comp--replace-output-file' and update so it can be used for replacing or deleting shared libs safetly. * lisp/emacs-lisp/package.el (package--delete-directory): When native compiled just call `comp-clean-up-stale-eln' for each eln file we want to clean-up. * src/alloc.c (cleanup_vector): Call directly the dynlib_close. * src/comp.c (syms_of_comp): Update for comp_u->cfile removal. Make 'all_loaded_comp_units_h' key-value weak as now the key will be the filename. (load_comp_unit): Register the compilation unit only when the load is fully completed. (register_native_comp_unit): Make the key of all_loaded_comp_units_h the load filename. (eln_load_path_final_clean_up): New function. (dispose_comp_unit) (finish_delayed_disposal_of_comp_units) (dispose_all_remaining_comp_units) (clean_package_user_dir_of_old_comp_units): Remove. (Fcomp__compile_ctxt_to_file): Update for `comp--replace-output-file' -> `comp-delete-or-replace-file' rename. * src/comp.h (dispose_comp_unit) (finish_delayed_disposal_of_comp_units) (dispose_all_remaining_comp_units) (clean_package_user_dir_of_old_comp_units): Remove. (eln_load_path_final_clean_up): Add. (struct Lisp_Native_Comp_Unit): Remove cfile field. * src/emacs.c (Fkill_emacs): Call 'eln_load_path_final_clean_up'. * src/pdumper.c (dump_do_dump_relocation): Do not set comp_u->cfile.
This commit is contained in:
parent
eb87425988
commit
a71f54eff8
7 changed files with 75 additions and 293 deletions
|
@ -2505,31 +2505,52 @@ Prepare every function for final compilation and drive the C back-end."
|
|||
|
||||
;; Some entry point support code.
|
||||
|
||||
(defun comp--replace-output-file (outfile tmpfile)
|
||||
"Replace OUTFILE with TMPFILE.
|
||||
Takes the necessary steps when dealing with shared libraries that
|
||||
may be loaded into Emacs"
|
||||
;;;###autoload
|
||||
(defun comp-clean-up-stale-eln (file)
|
||||
"Given FILE remove all the .eln files in `comp-eln-load-path'
|
||||
sharing the original source filename (including FILE)."
|
||||
(string-match (rx "-" (group-n 1 (1+ hex)) "-" (1+ hex) ".eln" eos) file)
|
||||
(cl-loop
|
||||
with filename-hash = (match-string 1 file)
|
||||
with regexp = (rx-to-string
|
||||
`(seq "-" ,filename-hash "-" (1+ hex) ".eln" eos))
|
||||
for dir in (butlast comp-eln-load-path) ; Skip last dir.
|
||||
do (cl-loop
|
||||
for f in (directory-files (concat dir comp-native-version-dir) t regexp
|
||||
t)
|
||||
do (comp-delete-or-replace-file f))))
|
||||
|
||||
(defun comp-delete-or-replace-file (oldfile &optional newfile)
|
||||
"Replace OLDFILE with NEWFILE.
|
||||
When NEWFILE is nil just delete OLDFILE.
|
||||
Takes the necessary steps when dealing with OLDFILE being a
|
||||
shared libraries that may be currently loaded by a running Emacs
|
||||
session."
|
||||
(cond ((eq 'windows-nt system-type)
|
||||
(ignore-errors (delete-file outfile))
|
||||
(let ((retry t))
|
||||
(while retry
|
||||
(setf retry nil)
|
||||
(ignore-errors (delete-file oldfile))
|
||||
(while
|
||||
(condition-case _
|
||||
(progn
|
||||
;; outfile maybe recreated by another Emacs in
|
||||
;; oldfile maybe recreated by another Emacs in
|
||||
;; between the following two rename-file calls
|
||||
(if (file-exists-p outfile)
|
||||
(rename-file outfile (make-temp-file-internal
|
||||
(file-name-sans-extension outfile)
|
||||
(if (file-exists-p oldfile)
|
||||
(rename-file oldfile (make-temp-file-internal
|
||||
(file-name-sans-extension oldfile)
|
||||
nil ".eln.old" nil)
|
||||
t))
|
||||
(rename-file tmpfile outfile nil))
|
||||
(file-already-exists (setf retry t))))))
|
||||
(when newfile
|
||||
(rename-file newfile oldfile nil))
|
||||
;; Keep on trying.
|
||||
nil)
|
||||
(file-already-exists
|
||||
;; Done
|
||||
t))))
|
||||
;; Remove the old eln instead of copying the new one into it
|
||||
;; to get a new inode and prevent crashes in case the old one
|
||||
;; is currently loaded.
|
||||
(t (delete-file outfile)
|
||||
(rename-file tmpfile outfile))))
|
||||
(t (delete-file oldfile)
|
||||
(when newfile
|
||||
(rename-file newfile oldfile)))))
|
||||
|
||||
(defvar comp-files-queue ()
|
||||
"List of Elisp files to be compiled.")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue