Fix worldgen async catcher deadlock

This commit is contained in:
IzzelAliz 2020-11-28 23:30:47 +08:00
parent c050ec7f6b
commit 9d27ae8627
3 changed files with 12 additions and 4 deletions

View File

@ -18,5 +18,7 @@ public interface MinecraftServerBridge {
void bridge$queuedProcess(Runnable runnable);
void bridge$drainQueuedTasks();
boolean bridge$hasStopped();
}

View File

@ -296,10 +296,15 @@ public abstract class MinecraftServerMixin extends RecursiveEventLoop<TickDelaye
private void executeModerately() {
this.drainTasks();
this.bridge$drainQueuedTasks();
java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L);
}
@Override
public void bridge$drainQueuedTasks() {
while (!processQueue.isEmpty()) {
processQueue.remove().run();
}
java.util.concurrent.locks.LockSupport.parkNanos("executing tasks", 1000L);
}
@Inject(method = "isAheadOfTime", cancellable = true, at = @At("HEAD"))
@ -445,9 +450,7 @@ public abstract class MinecraftServerMixin extends RecursiveEventLoop<TickDelaye
public void arclight$runScheduler(BooleanSupplier hasTimeLeft, CallbackInfo ci) {
ArclightConstants.currentTick = (int) (System.currentTimeMillis() / 50);
this.server.getScheduler().mainThreadHeartbeat(this.tickCounter);
while (!processQueue.isEmpty()) {
processQueue.remove().run();
}
this.bridge$drainQueuedTasks();
}
/**

View File

@ -1,7 +1,9 @@
package io.izzel.arclight.common.mixin.core.world.server;
import io.izzel.arclight.common.bridge.server.MinecraftServerBridge;
import io.izzel.arclight.common.bridge.world.server.ChunkManagerBridge;
import io.izzel.arclight.common.bridge.world.server.ServerChunkProviderBridge;
import io.izzel.arclight.common.mod.server.ArclightServer;
import net.minecraft.util.concurrent.ThreadTaskExecutor;
import net.minecraft.world.server.ServerChunkProvider;
import org.spongepowered.asm.mixin.Final;
@ -35,6 +37,7 @@ public abstract class ServerChunkProvider_ChunkExecutorMixin extends ThreadTaskE
}
} finally {
((ChunkManagerBridge) outer.chunkManager).bridge$getCallbackExecutor().run();
((MinecraftServerBridge) ArclightServer.getMinecraftServer()).bridge$drainQueuedTasks();
}
}
}