On Tue, 17 Dec 2024 11:51:51 GMT, Magnus Ihse Bursie <i...@openjdk.org> wrote:

> To be able to properly support static builds on Windows in 
> [JDK-8346377](https://bugs.openjdk.org/browse/JDK-8346377), we cannot use 
> `DllMain`, for two reasons:
> 
> 1) This is not called for statically linked libraries, and
> 2) There are multiple `DllMain` definitions throughout the JDK native 
> libraries, causing name collisions.
> 
> While it could have been possible to keep the `DllMain` function for 
> non-static builds and just use an alternative solution for static builds, I 
> think it is preferable to have a single solution that works as well for both 
> static and dynamic builds.
> 
> In this case, the `DllMain` function did two things: 
> 
> 1) At startup, it called SetModuleHandle. This has been moved to the 
> `JNI_OnLoad` function, which is called by the JVM right after loading the 
> DLL, or in the case of a static build, when the `awt` native library has been 
> requested.
> 
> 2) At DLL unload -- for debug builds only -- it "disabled" the mutexes for 
> the DTrace and DMem debug systems. In this case, "disable" means writing NULL 
> to the mutexes, causing any further calls to the continue without locking, 
> since the enter/exit calls only do the locking if the mutex is not NULL. 
> (This is pre-existing code so I am not discussing the soundness of this 
> approach.) 
> 
> But why did we need to do that? After the DLL unloading, which is done by 
> Windows when the process is exiting, no code should be executing in AWT, 
> right? No, wrong. There are three static objects, one instance of 
> AwtDebugSupport and two instances of GDIHashtable, and the destructors of 
> these objects are called by Windows at the time of process shutdown. I have 
> not been able to confirm that the `DllMain` code is guaranteed to be called 
> before the destructors are called, so I guess the fact that this ever worked 
> has just been a lucky coincidence. 
> 
> I have solved this by disabling the mutexes in the destructors themselves, 
> thereby guaranteeing that they are disabled before the last few calls to the 
> DTrace/DMem calls are made. There is no guarantee in which order these 
> destructors are made, so I do the same on both locations. (There is no bad 
> effect from calling these twice in a row, it's just setting a mutex to NULL).
> 
> Finally, I have wrapped the `DEF_JNI_OnLoad` function in `extern "C" { ... 
> }`. This is needed since DEF_JNI_OnLoad is a macro that actually creates two 
> functions, where one is a wrapper calling the other which has a generated 
> name, and without this, the C++ name mangling messed things up. (To be clear: 
> this means tha...

This pull request has now been integrated.

Changeset: 893d00ac
Author:    Magnus Ihse Bursie <i...@openjdk.org>
URL:       
https://git.openjdk.org/jdk/commit/893d00ac7d118620b56ce147d447c6fca80bbe7b
Stats:     46 lines in 1 file changed: 19 ins; 26 del; 1 mod

8346388: Cannot use DllMain in libawt for static builds

Reviewed-by: aivanov, prr

-------------

PR: https://git.openjdk.org/jdk/pull/22790

Reply via email to