Can reproduce; there's one less thread_detach than _attach. Output with my quad-core:
> program.exe
DLL_PROCESS_ATTACH
End...
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
DLL_THREAD_DETACH
DLL_THREAD_DETACH
DLL_PROCESS_DETACH
> program.exe --DRT-gcopt=parallel:0
Start loading.
Start Dynamic Link...
DLL_PROCESS_ATTACH
End...
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_PROCESS_DETACH
> program.exe --DRT-gcopt=disable:1
Start loading.
Start Dynamic Link...
DLL_PROCESS_ATTACH
End...
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_ATTACH
DLL_THREAD_DETACH
DLL_THREAD_DETACH
DLL_THREAD_DETACH
DLL_PROCESS_DETACH
The output is the same but the program doesn't hang anymore when using a more complete DllMain (extended core.sys.windows.dll.SimpleDllMain mixin):
extern (Windows)
BOOL DllMain(HINSTANCE hInstance, uint ulReason, void* reserved)
{
import core.sys.windows.winnt;
import core.sys.windows.dll :
dll_process_attach, dll_process_detach,
dll_thread_attach, dll_thread_detach;
switch (ulReason)
{
default: assert(0);
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH\n");
return dll_process_attach( hInstance, true );
case DLL_PROCESS_DETACH:
printf("DLL_PROCESS_DETACH\n");
dll_process_detach( hInstance, true );
return true;
case DLL_THREAD_ATTACH:
printf("DLL_THREAD_ATTACH\n");
return dll_thread_attach( true, true );
case DLL_THREAD_DETACH:
printf("DLL_THREAD_DETACH\n");
return dll_thread_detach( true, true );
}
}
Comment #3 by r.sagitario — 2019-12-07T19:17:24Z
Indeed, calling Runtime.initialize(); and Runtime.terminate(); in DllMain is not good enough (and never really has been). Is this still proposed somewhere? Is this a documentation issue?
> https://wiki.dlang.org/Win32_DLLs_in_D#D_code_calling_D_code_in_DLLs
IMO the gcProxy approach is so limited (no multi-threading, no sharing of other resources) that we should rather remove that section or add a large flashing warning at the top. We need something like https://dconf.org/2016/talks/thaut.html to support sharing the runtime across DLLs.
If someone actually uses the gcProxy, a simple fix should be to disable parallel marking by adding this line
extern (C) __gshared string[] rt_options = ["gcopt=parallel:0"];
Comment #6 by robert.schadek — 2024-12-07T13:39:51Z