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 a97bf06a0e8ba1cd612f7e8be2585bfdfbdfa969..2af478902b528f335797c691730afb2657d4e6c4 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(); } }