From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 24 Apr 2020 09:06:15 -0700 Subject: [PATCH] Make CallbackExecutor strict again The correct fix for double scheduling is to avoid it. The reason this class is used is because double scheduling causes issues elsewhere, and it acts as an explicit detector of what double schedules. Effectively, use the callback executor as a tool of finding issues rather than hiding these issues. diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index d9f6d47629f2f4aa1db5a19b8cb7229a0905b75e..dec387e56928fa9b07a183e3055489dfe3dd94fe 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -160,17 +160,28 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider public final CallbackExecutor callbackExecutor = new CallbackExecutor(); public static final class CallbackExecutor implements java.util.concurrent.Executor, Runnable { - private final java.util.Queue queue = new java.util.ArrayDeque<>(); + private Runnable queued; // Paper - revert CB changes @Override public void execute(Runnable runnable) { - this.queue.add(runnable); + // Paper start - revert CB changes + org.spigotmc.AsyncCatcher.catchOp("Callback Executor execute"); + if (this.queued != null) { + net.minecraft.server.MinecraftServer.LOGGER.fatal("Failed to schedule runnable", new IllegalStateException("Already queued")); + throw new IllegalStateException("Already queued"); + } + this.queued = runnable; + // Paper end - revert CB changes } @Override public void run() { - Runnable task; - while ((task = this.queue.poll()) != null) { + // Paper start - revert CB changes + org.spigotmc.AsyncCatcher.catchOp("Callback Executor execute"); + Runnable task = this.queued; + if (task != null) { + this.queued = null; + // Paper end - revert CB changes task.run(); } }