Skip to content

Class-init deadlock with GTM Extended Features during CONSTRUCT (RenderStateShard ↔ WriteMaskStateShard) #2184

Description

@dikivan2000

Note: the following has been generated with help from Claude AI. I myself know very little of the programming intricacies but wish to be as helpful as possible in my reporting. If this was not helpful, I would appreciate you letting me know so I can gather more data and help resolve the issue rather than berating as is so often done. Thank you.

Environment
Minecraft 1.20.1, Forge 47.4.23, Java 17.0.15 (Microsoft)
Immersive Vehicles 24.0.0 + Official Pack V29
GTM Extended Features 2.4.0, GTCEu 7.5.3, GT-- 1.3.10

Symptom
Loading hangs indefinitely on "Dispatching CONSTRUCT event". No crash report. Reproducible on most launches with default fml.toml maxThreads; two thread dumps taken ~50 s apart are identical (attached).

Cause (from the dumps)
Two modloading workers deadlock on class initialisation of vanilla's RenderStateShard and its nested subclass RenderStateShard$WriteMaskStateShard, which initialise each other:

"modloading-worker-0" #42 — Immersive Vehicles
  at net.minecraft.client.renderer.RenderStateShard.<clinit>(RenderStateShard.java:438)
  - waiting on the Class initialization monitor for net.minecraft.client.renderer.RenderStateShard$WriteMaskStateShard
  at mcinterface1201.InterfaceRender.<clinit>(InterfaceRender.java:98)
  at mcinterface1201.InterfaceLoader.init(InterfaceLoader.java:104)

"modloading-worker-0" #52 — GTM Extended Features
  at com.extendedfeatures.init.utils.internal.rendering.range.RangeRenderer.<clinit>(RangeRenderer.java:60)
  - waiting on the Class initialization monitor for net.minecraft.client.renderer.RenderStateShard
  at java.lang.Class.forName ...
  at net.minecraftforge.fml.javafmlmod.AutomaticEventSubscriber.lambda$inject$6(AutomaticEventSubscriber.java:61)

IV's InterfaceRender.<clinit> (called from InterfaceLoader.init on a modloading worker) triggers initialisation of RenderStateShard, whose static initialiser instantiates its nested shard classes. At the same moment GTEF's RangeRenderer static initialiser, loaded via @EventBusSubscriber on another worker, touches WriteMaskStateShard first, and that nested class needs its parent initialised. Each thread holds the monitor the other needs. Deferring InterfaceRender's RenderType/shard setup out of <clinit> (e.g. to the render thread or first use), or force-initialising RenderStateShard before referencing any nested shard, would break the cycle on IV's side.

Workaround
config/fml.toml → maxThreads = 1.

Cross-reference: NotArgxment/GT-Extended-Features#3

0.txt
1.txt

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions