From e6d60da06f0100329dee61f5f435aa0e03c9ddea Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sun, 5 Mar 2023 12:51:23 -0800 Subject: [PATCH] Halt chunk systems before saving chunks for all worlds This is to ensure that chunks are not progressing in other worlds while saving --- patches/server/0004-Threaded-Regions.patch | 36 ++++++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/patches/server/0004-Threaded-Regions.patch b/patches/server/0004-Threaded-Regions.patch index 11c2602..ab6f28c 100644 --- a/patches/server/0004-Threaded-Regions.patch +++ b/patches/server/0004-Threaded-Regions.patch @@ -3773,10 +3773,10 @@ index 0000000000000000000000000000000000000000..d9687722e02dfd4088c7030abbf5008e +} diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java b/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java new file mode 100644 -index 0000000000000000000000000000000000000000..cd97607d188b8c0cf44af2185b345bf4c5c578bd +index 0000000000000000000000000000000000000000..55c6387b6507b6495958ab4cbdceee386ac9cfca --- /dev/null +++ b/src/main/java/io/papermc/paper/threadedregions/RegionShutdownThread.java -@@ -0,0 +1,157 @@ +@@ -0,0 +1,173 @@ +package io.papermc.paper.threadedregions; + +import com.mojang.logging.LogUtils; @@ -3871,12 +3871,12 @@ index 0000000000000000000000000000000000000000..cd97607d188b8c0cf44af2185b345bf4 + } + + private void saveRegionChunks(final ThreadedRegioniser.ThreadedRegion region, -+ final boolean first, final boolean last) { ++ final boolean last) { + final ChunkPos center = region.getCenterChunk(); + LOGGER.info("Saving chunks around region around chunk " + center + " in world '" + region.regioniser.world.getWorld().getName() + "'"); + try { + this.shuttingDown = region; -+ region.regioniser.world.chunkTaskScheduler.chunkHolderManager.close(true, true, first, last, false); ++ region.regioniser.world.chunkTaskScheduler.chunkHolderManager.close(true, true, false, last, false); + } catch (final Throwable thr) { + LOGGER.error("Failed to save chunks for region around chunk " + center + " in world '" + region.regioniser.world.getWorld().getName() + "'", thr); + } finally { @@ -3884,6 +3884,14 @@ index 0000000000000000000000000000000000000000..cd97607d188b8c0cf44af2185b345bf4 + } + } + ++ private void haltChunkSystem(final ServerLevel world) { ++ try { ++ world.chunkTaskScheduler.chunkHolderManager.close(false, true, true, false, false); ++ } catch (final Throwable thr) { ++ LOGGER.error("Failed to halt chunk system for world '" + world.getWorld().getName() + "'", thr); ++ } ++ } ++ + private void haltWorldNoRegions(final ServerLevel world) { + try { + world.chunkTaskScheduler.chunkHolderManager.close(true, true, true, true, false); @@ -3903,6 +3911,19 @@ index 0000000000000000000000000000000000000000..cd97607d188b8c0cf44af2185b345bf4 + } + + MinecraftServer.getServer().stopServer(); // stop part 1: most logic, kicking players, plugins, etc ++ // halt all chunk systems first so that any in-progress chunk generation stops ++ LOGGER.info("Halting chunk systems"); ++ for (final ServerLevel world : MinecraftServer.getServer().getAllLevels()) { ++ try { ++ world.chunkTaskScheduler.halt(false, 0L); ++ } catch (final Throwable throwable) { ++ LOGGER.error("Failed to soft halt chunk system for world '" + world.getWorld().getName() + "'", throwable); ++ } ++ } ++ for (final ServerLevel world : MinecraftServer.getServer().getAllLevels()) { ++ this.haltChunkSystem(world); ++ } ++ LOGGER.info("Halted chunk systems"); + for (final ServerLevel world : MinecraftServer.getServer().getAllLevels()) { + final List> + regions = new ArrayList<>(); @@ -3915,12 +3936,7 @@ index 0000000000000000000000000000000000000000..cd97607d188b8c0cf44af2185b345bf4 + + for (int i = 0, len = regions.size(); i < len; ++i) { + final ThreadedRegioniser.ThreadedRegion region = regions.get(i); -+ this.saveRegionChunks(region, i == 0, (i + 1) == len); -+ } -+ -+ if (regions.isEmpty()) { -+ // still need to halt the chunk system -+ this.haltWorldNoRegions(world); ++ this.saveRegionChunks(region, (i + 1) == len); + } + + this.saveLevelData(world);