Improved chunk deadlock detection system + patch Valhelsia Structures
when installed
This commit is contained in:
parent
10149e9f87
commit
e977fcdfce
|
|
@ -98,6 +98,7 @@ dependencies {
|
|||
modRuntimeOnly("curse.maven:ferritecore-429235:4074330")
|
||||
modCompileOnly("team.chisel.ctm:CTM:${ctm_version}")
|
||||
modCompileOnly("curse.maven:supermartijncore-454372:4455378")
|
||||
modCompileOnly("curse.maven:valhesiastructures-347488:3476252")
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
|
|
|
|||
|
|
@ -251,6 +251,14 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if(mixinClassName.equals("org.embeddedt.modernfix.mixin.bugfix.chunk_deadlock.valhesia.BlockStateBaseMixin")) {
|
||||
// We need to destroy Valhelsia's callback so it can never run getBlockState
|
||||
for(MethodNode m : targetClass.methods) {
|
||||
if(m.name.contains("valhelsia_placeDousedTorch")) {
|
||||
m.instructions.clear();
|
||||
m.instructions.add(new InsnNode(Opcodes.RETURN));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,6 +50,7 @@ public class ModernFixEarlyConfig {
|
|||
this.addMixinRule("bugfix.structure_manager_crash", true);
|
||||
this.addMixinRule("bugfix.mc218112", true);
|
||||
this.addMixinRule("bugfix.chunk_deadlock", true);
|
||||
this.addMixinRule("bugfix.chunk_deadlock.valhesia", modPresent("valhelsia_structures"));
|
||||
this.addMixinRule("bugfix.tf_cme_on_load", modPresent("twilightforest"));
|
||||
this.addMixinRule("bugfix.refinedstorage", modPresent("refinedstorage"));
|
||||
this.addMixinRule("perf.async_jei", modPresent("jei"));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.chunk_deadlock;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
|
@ -13,12 +15,18 @@ import org.spongepowered.asm.mixin.Shadow;
|
|||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
@Mixin(value = ServerChunkCache.class, priority = 1100)
|
||||
public abstract class ServerChunkCacheMixin {
|
||||
@Shadow @Final private Thread mainThread;
|
||||
@Shadow @Final public ServerLevel level;
|
||||
|
||||
@Shadow protected abstract CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkFutureMainThread(int k, int l, ChunkStatus arg, boolean bl);
|
||||
|
||||
@Shadow @Final private ServerChunkCache.MainThreadExecutor mainThreadProcessor;
|
||||
private final boolean debugDeadServerAccess = Boolean.getBoolean("modernfix.debugBadChunkloading");
|
||||
|
||||
@Inject(method = "getChunk", at = @At("HEAD"), cancellable = true)
|
||||
private void bailIfServerDead(int chunkX, int chunkZ, ChunkStatus requiredStatus, boolean load, CallbackInfoReturnable<ChunkAccess> cir) {
|
||||
if(!this.mainThread.isAlive()) {
|
||||
|
|
@ -27,6 +35,34 @@ public abstract class ServerChunkCacheMixin {
|
|||
new Exception().printStackTrace();
|
||||
}
|
||||
cir.setReturnValue(new EmptyLevelChunk(this.level, new ChunkPos(chunkX, chunkZ)));
|
||||
} else if(Thread.currentThread() != this.mainThread) {
|
||||
CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> future = CompletableFuture.supplyAsync(() -> this.getChunkFutureMainThread(chunkX, chunkZ, requiredStatus, false), this.mainThreadProcessor).join();
|
||||
if(!future.isDone()) {
|
||||
// Wait at least 500 milliseconds before printing anything
|
||||
Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> resultingChunk = null;
|
||||
try {
|
||||
resultingChunk = future.get(500, TimeUnit.MILLISECONDS);
|
||||
} catch(InterruptedException | ExecutionException | TimeoutException ignored) {
|
||||
}
|
||||
if(resultingChunk != null && resultingChunk.left().isPresent()) {
|
||||
cir.setReturnValue(resultingChunk.left().get());
|
||||
return;
|
||||
}
|
||||
if(debugDeadServerAccess)
|
||||
ModernFix.LOGGER.warn("Async loading of a chunk was requested, this might not be desirable", new Exception());
|
||||
else
|
||||
ModernFix.LOGGER.warn("Suspicious async chunkload, pass -Dmodernfix.debugBadChunkloading=true for more details");
|
||||
try {
|
||||
resultingChunk = future.get(10, TimeUnit.SECONDS);
|
||||
if(resultingChunk.left().isPresent()) {
|
||||
cir.setReturnValue(resultingChunk.left().get());
|
||||
return;
|
||||
}
|
||||
} catch(InterruptedException | ExecutionException | TimeoutException e) {
|
||||
ModernFix.LOGGER.error("Async chunk load took way too long, this needs to be reported to the appropriate mod.", e);
|
||||
}
|
||||
//cir.setReturnValue(new EmptyLevelChunk(this.level, new ChunkPos(chunkX, chunkZ)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package org.embeddedt.modernfix.mixin.bugfix.chunk_deadlock.valhesia;
|
||||
|
||||
import com.stal111.valhelsia_structures.init.ModBlocks;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(value = BlockBehaviour.BlockStateBase.class, priority = 900)
|
||||
public abstract class BlockStateBaseMixin {
|
||||
@Shadow public abstract Block getBlock();
|
||||
|
||||
/**
|
||||
* Do not call getBlockState here; this can cause deadlocks during world gen/lighting.
|
||||
*/
|
||||
@Inject(method = "getOffset", at = @At("HEAD"), cancellable = true)
|
||||
private void useThisBlock(BlockGetter getter, BlockPos pos, CallbackInfoReturnable<Vec3> cir) {
|
||||
if(this.getBlock() == ModBlocks.BONE_PILE.get())
|
||||
cir.setReturnValue(new Vec3(0.0, -0.46875, 0.0));
|
||||
}
|
||||
}
|
||||
|
|
@ -29,8 +29,9 @@ public class IntegratedWatchdog extends Thread {
|
|||
while(server.isRunning()) {
|
||||
long nextTick = this.server.getNextTickTime();
|
||||
long curTime = Util.getMillis();
|
||||
if((curTime - nextTick) > MAX_TICK_DELTA) {
|
||||
LOGGER.error("A single server tick has taken {}, more than {} milliseconds", (nextTick - curTime), MAX_TICK_DELTA);
|
||||
long delta = curTime - nextTick;
|
||||
if(delta > MAX_TICK_DELTA) {
|
||||
LOGGER.error("A single server tick has taken {}, more than {} milliseconds", delta, MAX_TICK_DELTA);
|
||||
ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean();
|
||||
ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
|
|
|||
|
|
@ -22,4 +22,5 @@ public net.minecraft.block.AbstractBlock$Properties field_235817_s_ # isViewBloc
|
|||
public net.minecraft.block.AbstractBlock$Properties field_235818_t_ # hasPostProcess
|
||||
public net.minecraft.block.AbstractBlock$Properties field_235819_u_ # emissiveRendering
|
||||
public net.minecraft.block.AbstractBlock$Properties field_235806_h_ # requiresCorrectToolForDrops
|
||||
public net.minecraft.block.AbstractBlock$Properties field_200959_g # destroyTime
|
||||
public net.minecraft.block.AbstractBlock$Properties field_200959_g # destroyTime
|
||||
public net.minecraft.world.server.ServerChunkProvider$ChunkExecutor
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
"bugfix.refinedstorage.te_bug.ItemExternalStorageCacheMixin",
|
||||
"bugfix.refinedstorage.te_bug.ItemExternalStorageMixin",
|
||||
"bugfix.chunk_deadlock.ServerChunkCacheMixin",
|
||||
"bugfix.chunk_deadlock.valhesia.BlockStateBaseMixin",
|
||||
"perf.remove_biome_temperature_cache.BiomeMixin",
|
||||
"perf.resourcepacks.ModFileResourcePackMixin",
|
||||
"perf.resourcepacks.VanillaPackMixin",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user