On Thursday, 20 October 2016 at 07:17:49 UTC, Benjamin Thaut
wrote:
This is a topic really specific to druntime, I don't know a
better place to put it though.
rt_init increases the _initCount and rt_term decreases it and
only terminates the runtime in case the _initCount reaches zero
(see dmain2.d)
The problem now is as follows.
Each dynamic library that is loaded (in this case a .dll on
windows) must ensure that druntime is intialized. This must be
done to ensure that d dynamic libraries work with C processes
that load them. So lets assume we have a exe and two dlls: DllA
and DllB. The exe uses the two dlls and druntime. What will
happen is the following
1) Exe starts up
2) The windows loader will load DllA. This will call rt_init
_initCount will be 1. Druntime will be initialized. Module
ctors of druntime will be called. Module Ctors of DllA will be
called.
3) The windows loader will load DllB. _initCount will be 2.
Module Ctors of DllB will be called.
4) The dmain function will be execued. It will call rt_init.
_initCount is 3. Module ctors of exe will be called.
5) Dmain finishes and calls rt_term. _initCount is 2. Nothing
happens
6) The windows loader will unload DllB. rt_term is called.
_initCount is 1. DllB is forced to call its module dtors.
7) The windows loader will unload DllA. r_term is called.
_initCount is 0. Module Dtors of exe will be called. Module
Dotrs of DllA will be called. Module Dtors of druntime will be
called.
As might observed the issue is the order in which the module
dtors are called. The order is
Druntime Ctor
DllA Ctor
DllB Ctor
ExE Ctor
DllB Dtor
Exe Dtor
DllA Dtor
Druntime Dtor
Whereas it should be:
Druntime Ctor
DllA Ctor
DllB Ctor
ExE Ctor
Exe Dtor
DllB Dtor
DllA Dtor
Druntime Dtor
The problem is step 5) in the above list. When the main
executable leaves dmain the runtime should be deinitialized no
matter if any dll is still loaded or not. If this would be the
case the module Dtors would be calle din the correct order. I
can't remove the rt_init calls from the dll loading code
however because that would mean when loading a d-dll into a C
process druntime would never be initialized. So I'm thinking of
adding a force parameter to rt_term which will always
deinitialize druntime disregarding the _initCount. This feels
like a hack though.
Any suggestions how to solve this problem? Who are other
platforms doing it?
Kind Regards
Benjamin Thaut
I don't know anything about the druntime code but the solution
seems to look like rt_term() should kick the call to the
destructor when the initcound matches with the initcount it had
when it called rt_init(). But as I already said, I'm talking out
of my ass here as I never even looked in the code.