From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Wed, 19 Jun 2024 10:52:07 -0700 Subject: [PATCH] Add debug for chunk system unload crash Somehow, a chunkholder is present in the unload queue after it has been unloaded. It is likely that this is a result of adding the chunk holder to the unload queue while it is unloading. However, that should not be possible. To find out where it is being added to the unload queue, track the last stacktrace which adds to the unload queue and check on chunk holder remove if the holder is present in the unload queue and log the stacktrace. diff --git a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java index 1dfddea4fd7e89fb6fd9fa49f7ab5e6f48e6ef3c..4068138e4ec0ccb02f5925f8b5a31381882f08e0 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java @@ -749,9 +749,22 @@ public final class NewChunkHolder { /** Unloaded from chunk map */ private boolean unloaded; + private Throwable lastUnloadAdd; void markUnloaded() { this.unloaded = true; + if (this.inUnloadQueue) { + if (this.lastUnloadAdd != null) { + LOGGER.error("Unloaded chunkholder " + this.toString() + " while in the unload queue", this.lastUnloadAdd); + } else { + // should never happen + LOGGER.error("Unloaded chunkholder " + this.toString() + " while in the unload queue without a throwable"); + } + + // prevent crash by removing (note: we hold scheduling lock here) + this.inUnloadQueue = false; + this.scheduler.chunkHolderManager.unloadQueue.removeChunk(this.chunkX, this.chunkZ); + } } private boolean inUnloadQueue = false; @@ -769,12 +782,14 @@ public final class NewChunkHolder { // ensure in unload queue if (!this.inUnloadQueue) { this.inUnloadQueue = true; + this.lastUnloadAdd = new Throwable(); this.scheduler.chunkHolderManager.unloadQueue.addChunk(this.chunkX, this.chunkZ); } } else { // ensure not in unload queue if (this.inUnloadQueue) { this.inUnloadQueue = false; + this.lastUnloadAdd = null; this.scheduler.chunkHolderManager.unloadQueue.removeChunk(this.chunkX, this.chunkZ); } }