There has been a latent problem in `GDIHashtable` since time immemorial, but 
due to sheer luck it has not caused any issues for us. However, I managed to 
provoke it when I was doing some build changes.

This is the problem:
In `GDIHashtable`, there is a static field 
`GDIHashtable::BatchDestructionManager manager`, which is initialized in 
`GDIHashtable.cpp`.

In `AwtPen`, there is a static field `GDIHashtable cache`, which is initialized 
in `awt_Pen.cpp`.

The `GDIHashtable` constructor calls `manager.add(this)`.

For this to work, the manager must have been initialized prior to the AwtPen. 
However, the order of which static initializers are run between different 
compilation units are not well-defined, and we've just been lucky so far that 
it works.

This problem is known as the "Static Initialization Order Fiasco", see e.g. 
https://en.cppreference.com/w/cpp/language/siof

I have solved this by encapsulating the static manager instance in a method, 
which guarantees that it has been initialized before use. This seemed to me to 
be the cleanest solution.

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

Commit messages:
 - 8346195: Fix static initialization problem in GDIHashtable

Changes: https://git.openjdk.org/jdk/pull/22736/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=22736&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8346195
  Stats: 14 lines in 2 files changed: 3 ins; 2 del; 9 mod
  Patch: https://git.openjdk.org/jdk/pull/22736.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/22736/head:pull/22736

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

Reply via email to