Skip to content

Main thread deadlock in CustomBlockListener.getMaterialId() (LocalCache lock contention) #43

Description

@ppatoo

I'm on Leaf 1.21.11-168-ea288d3 (MC 1.21.11), Java 25 and Running TuffXPlus v1.1.0. Been a like full-server freezes (10+ seconds each) where the watchdog kicks in and dumps a thread trace. I'm not sure if its because something else is causing it but the main thread is stuck waiting on a lock inside a Guava LocalCache, called from your CustomBlockListener:

com.google.common.cache.LocalCache$Segment.put(LocalCache.java:2795)
com.google.common.cache.LocalCache.put(LocalCache.java:4213)
com.google.common.cache.LocalCache$LocalManualCache.put(LocalCache.java:4871)
TuffXPlus-1.1.0.jar//tf.tuff.viablocks.CustomBlockListener.getMaterialId(CustomBlockListener.java:586)
TuffXPlus-1.1.0.jar//tf.tuff.viablocks.CustomBlockListener.handleBlockPhysics(CustomBlockListener.java:487)
TuffXPlus-1.1.0.jar//tf.tuff.TuffX.onBlockPhysics(TuffX.java:264)

First one, triggered by plant growth:

net.minecraft.world.level.block.GrowingPlantHeadBlock.randomTick(GrowingPlantHeadBlock.java:62)
net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase.randomTick(BlockBehaviour.java:906)
org.dreeam.leaf.world.RandomTickSystem.tickBlock(RandomTickSystem.java:265)
org.dreeam.leaf.world.RandomTickSystem.tick(RandomTickSystem.java:71)
net.minecraft.server.level.ServerChunkCache.tickChunks(ServerChunkCache.java:683)
... then down into Level.setBlock -> notifyAndUpdatePhysics -> your listener and the same cache lock as above

Second one, triggered by a trial spawner ticking:

net.minecraft.world.level.block.entity.trialspawner.TrialSpawner.tickServer(TrialSpawner.java:294)
net.minecraft.world.level.block.entity.trialspawner.TrialSpawner.setState(TrialSpawner.java:134)
net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity.setState(TrialSpawnerBlockEntity.java:87)
net.minecraft.world.level.Level.setBlockAndUpdate(Level.java:1321)

Since two totally unrelated events both hang in the exact same spot, it really seems like the cache in getMaterialId() (line 586) is either getting written to from another thread at the same time as the main thread, or something is holding onto that lock way longer than it should while doing other work.

I did also enable a few experimental modules enabled: [MultithreadedTracker.enabled, OptimizeDespawn.enabled, OptimizeMobSpawning.enabled, OptimizeRandomTick.enabled]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions