Subject: Re: bug#41242: Port feature/native-comp to Windows

From: Nicolas Bértolo <[email-masked]>
Date: Thu, 14 May 2020 13:50:48 -0300

> Loading a new compilation unit B that redefines the same functions
> defined by A does not guarantees much, some of the old definitions of A
> could be still in use somewhere, in that case A will not be collected.

> So yeah I think we need a specific mechanism (kill-emacs hook as you
> suggest) to do the cleanup when Emacs goes down.

I was thinking about something like this:

1) Call `native-comp-unload`.

2) This should inspect the eln file and put all the subrs defined in it on a
list. This should also copy the original bytecode from the eln file and store it
somewhere.

3) Then `garbage-collect` is called. This should find all references to the
subrs in the list and swap them atomically for references to functions
from the bytecode.

4) After the previous step the GC should be able to collect the DLL handle
knowing that no references to it remain.

What do you think?

> No you are right, I don't use Windows since forever, I discovered from
> this thread is not portable.  I guess we'll need to rename also here.

But someone needs to delete the old eln file. Let's say that we use
GetModuleFileNameA() to know if another Emacs instance has decided to rename the
eln file and then we delete it on close if its suffix is ".eln.old".

This algorithm has a big race condition though. If Emacs1 renames the file after
Emacs2 has checked that it has not been renamed, then the file won't be deleted.
If we put the "old eln" in the $TEMP folder this may not be a big issue though.

Nicolas.

El jue., 14 may. 2020 a las 12:03, Andrea Corallo (<[email-masked]>) escribió:
>
> Eli Zaretskii <[email-masked]> writes:
>
> >> From: Andrea Corallo <[email-masked]>
> >> Cc: [email-masked],
> >>         Nicolas Bértolo
> >>  <[email-masked]>,
> >>         [email-masked]
> >> Date: Thu, 14 May 2020 11:17:11 +0000
> >>
> >> > Windows doesn't let you delete a shared library that's loaded by a
> >> > process, but it does let you rename it.  So I think the solution would
> >> > be to rename the .eln file to something like .eln.old, and then let
> >> > the GC driven unload machinery to delete that old file.
> >>
> >> Do we have guarantees that each object is collected before Emacs is
> >> eventually closed?  I thought is not the case.
> >
> > I don't know enough about the "GC driven unload" you mentioned, but if
> > that is not bulletproof enough, we could add a kill-emacs hook to take
> > care of this.  And if push comes to shove, we could use a Windows API
> > that causes a file to be deleted when the last handle on it is closed,
> > but that would add complexity, so I think we should try easier ways
> > first.
>
> Now simply when the compilation unit object is collected, the handle is
> closed.  The compilation unit is collected when is not reachable by any
> of the functions defined into.
>
> Loading a new compilation unit B that redefines the same functions
> defined by A does not guarantees much, some of the old definitions of A
> could be still in use somewhere, in that case A will not be collected.
>
> So yeah I think we need a specific mechanism (kill-emacs hook as you
> suggest) to do the cleanup when Emacs goes down.
>
> >> > Btw, what happens if more than one Emacs session have the same .eln file loaded, and one of them wants to recompile it?
> >>
> >> Now to avoid this problem we always delete the file before recompiling.
> >
> > But that's unportable, and won't work on Windows, for the same reasons
> > as the issue we are discussing here.  Or am I missing something?
>
> No you are right, I don't use Windows since forever, I discovered from
> this thread is not portable.  I guess we'll need to rename also here.
>
>   Andrea
>
> --
> [email-masked]