Skip to content

Commit

Permalink
Fix native code uneffective loads after recompilation
Browse files Browse the repository at this point in the history
'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.
  • Loading branch information
AndreaCorallo committed Aug 19, 2020
1 parent 886377f commit 8a931a9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 15 deletions.
19 changes: 17 additions & 2 deletions src/comp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))),
Expand Down
20 changes: 7 additions & 13 deletions src/lread.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand Down

0 comments on commit 8a931a9

Please sign in to comment.