From: Andrea Corallo Date: Wed, 19 Aug 2020 13:26:42 +0000 (+0200) Subject: Fix native code uneffective loads after recompilation X-Git-Tag: emacs-28.0.90~2727^2~482 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=8a931a97b8dd19a38d6f719f810280a07ba76438;p=emacs.git Fix native code uneffective loads after recompilation 'dlopen' can return the same handle if two shared with the same filename are loaded in two different times (even if the first was deleted!). To prevent this scenario the last modification time of the source file is included in the hashing algorithm. * src/comp.c (Fcomp_el_to_eln_filename): Update hashing algo to include the source last modification date. * src/lread.c (maybe_swap_for_eln): Do not check for eln newer then elc as this is now unnecessary. --- diff --git a/src/comp.c b/src/comp.c index ff73245b8de..a00088bb7f8 100644 --- a/src/comp.c +++ b/src/comp.c @@ -3872,13 +3872,26 @@ If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) { CHECK_STRING (filename); + if (NILP (Ffile_exists_p (filename))) + xsignal1 (Qfile_missing, filename); + + Lisp_Object last_mod_time = + Fnth (make_fixnum (5), Ffile_attributes (filename, Qnil)); + if (suffix_p (filename, ".gz")) filename = Fsubstring (filename, Qnil, make_fixnum (-3)); filename = Fexpand_file_name (filename, Qnil); /* We create eln filenames with an hash in order to look-up these starting from the source filename, IOW have a relation - /absolute/path/filename.el -> eln-cache/filename-hash.eln. + + /absolute/path/filename.el + last_mod_time -> + eln-cache/filename-hash.eln. + + 'dlopen' can return the same handle if two shared with the same + filename are loaded in two different times (even if the first was + deleted!). To prevent this scenario the last modification time + of the source file is included in the hashing algorithm. As installing .eln files compiled during the build changes their absolute path we need an hashing mechanism that is not sensitive @@ -3910,7 +3923,9 @@ If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) } } - Lisp_Object hash = Fsubstring (comp_hash_string (filename), Qnil, + Lisp_Object hash_input = + concat2 (filename, Fprin1_to_string (last_mod_time, Qnil)); + Lisp_Object hash = Fsubstring (comp_hash_string (hash_input), Qnil, make_fixnum (ELN_FILENAME_HASH_LEN)); filename = concat2 (Ffile_name_nondirectory (Fsubstring (filename, Qnil, make_fixnum (-3))), diff --git a/src/lread.c b/src/lread.c index 521da4e1d81..6b585fcaccc 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1635,19 +1635,13 @@ maybe_swap_for_eln (Lisp_Object *filename, int *fd, struct timespec mtime) emacs_close (eln_fd); else { - struct timespec eln_mtime = get_stat_mtime (&eln_st); - if (timespec_cmp (eln_mtime, mtime) > 0) - { - *filename = eln_name; - emacs_close (*fd); - *fd = eln_fd; - /* Store the eln -> el relation. */ - Fputhash (Ffile_name_nondirectory (eln_name), - el_name, Vcomp_eln_to_el_h); - return; - } - else - emacs_close (eln_fd); + *filename = eln_name; + emacs_close (*fd); + *fd = eln_fd; + /* Store the eln -> el relation. */ + Fputhash (Ffile_name_nondirectory (eln_name), + el_name, Vcomp_eln_to_el_h); + return; } } }