Re: rt_init, rt_term and _initCount

2016-10-22 Thread Benjamin Thaut via Digitalmars-d
On Saturday, 22 October 2016 at 07:12:48 UTC, Rainer Schuetze 
wrote:


Please also consider that the main executable might not know 
about DLLs being written in D. In that case all termination 
must be triggered by the druntime DLL.


The case where the main executable is not D is working fine. The 
problem at the moment is the case where the main executable is D. 
So I will be going for the dll registration approach then. As you 
said we can add in the thread join in case it becomes a problem.


Re: rt_init, rt_term and _initCount

2016-10-22 Thread Rainer Schuetze via Digitalmars-d



On 22.10.2016 01:21, Benjamin Thaut wrote:

On Friday, 21 October 2016 at 19:40:52 UTC, Rainer Schuetze wrote:


The wrapper around main in the executable should work just as any
DLLs' DllMain, i.e. it should register/unregister its own data
segments with the GC and run its shared and TLS module
constructors/decoontructors. Everything else should be handled by the
druntime DLL.


Yes, I also considered that option. The problem with that is, that
druntime deinit joins alls threads before running the shared module
dtors. If the main executable behaves exactly like the dlls do this
joining of threads would be lost and different from the behavior of a
fully statical linked executable.


The main executable wrapper could add this join-all if it is considered 
useful. I'm not really convinced: If there are actually threads still 
running on program termination, it's likely they need some signal to 
stop. In C++ that is usually fired in the shared destructor of some 
global. This is currently not possible in D as these are run after joinAll.


Please also consider that the main executable might not know about DLLs 
being written in D. In that case all termination must be triggered by 
the druntime DLL.


Re: rt_init, rt_term and _initCount

2016-10-21 Thread Benjamin Thaut via Digitalmars-d

On Friday, 21 October 2016 at 19:40:52 UTC, Rainer Schuetze wrote:


The wrapper around main in the executable should work just as 
any DLLs' DllMain, i.e. it should register/unregister its own 
data segments with the GC and run its shared and TLS module 
constructors/decoontructors. Everything else should be handled 
by the druntime DLL.


Yes, I also considered that option. The problem with that is, 
that druntime deinit joins alls threads before running the shared 
module dtors. If the main executable behaves exactly like the 
dlls do this joining of threads would be lost and different from 
the behavior of a fully statical linked executable.


Re: rt_init, rt_term and _initCount

2016-10-21 Thread Rainer Schuetze via Digitalmars-d



On 20.10.2016 09:17, 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 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?


I don't think the current rt_init/rt_exit function are suitable for DLLs 
or executables that are using a shared druntime library.


The wrapper around main in the executable should work just as any DLLs' 
DllMain, i.e. it should register/unregister its own data segments with 
the GC and run its shared and TLS module constructors/decoontructors. 
Everything else should be handled by the druntime DLL.


Re: rt_init, rt_term and _initCount

2016-10-20 Thread Benjamin Thaut via Digitalmars-d

On Thursday, 20 October 2016 at 08:44:09 UTC, Ethan Watson wrote:
On Thursday, 20 October 2016 at 07:17:49 UTC, Benjamin Thaut 
wrote:
Any suggestions how to solve this problem? Who are other 
platforms doing it?


Would this also be a bigger problem if people use LoadLibrary 
and don't FreeLibrary after?


No. This case actually works correctly. No worries I have your 
use case covered ;-)


Re: rt_init, rt_term and _initCount

2016-10-20 Thread Patrick Schluter via Digitalmars-d
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.


Re: rt_init, rt_term and _initCount

2016-10-20 Thread Ethan Watson via Digitalmars-d
On Thursday, 20 October 2016 at 07:17:49 UTC, Benjamin Thaut 
wrote:
Any suggestions how to solve this problem? Who are other 
platforms doing it?


Would this also be a bigger problem if people use LoadLibrary and 
don't FreeLibrary after?


rt_init, rt_term and _initCount

2016-10-20 Thread Benjamin Thaut via Digitalmars-d
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