diff options
Diffstat (limited to 'Spigot-Server-Patches-Unmapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch')
-rw-r--r-- | Spigot-Server-Patches-Unmapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/Spigot-Server-Patches-Unmapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch b/Spigot-Server-Patches-Unmapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch new file mode 100644 index 0000000000..9c719ad246 --- /dev/null +++ b/Spigot-Server-Patches-Unmapped/0449-Fix-Chunk-Post-Processing-deadlock-risk.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Sat, 18 Apr 2020 04:36:11 -0400 +Subject: [PATCH] Fix Chunk Post Processing deadlock risk + +See: https://gist.github.com/aikar/dd22bbd2a3d78a2fd3d92e95e9f28dc6 + +as part of post processing a chunk, we can call ChunkConverter. + +ChunkConverter then kicks off major physics updates, and when blocks +that have connections across chunk boundries occur, a recursive risk +can occur where A updates a block that triggers a physics request. + +That physics request may trigger a chunk request, that then enqueues +a task into the Mailbox ChunkTaskQueueSorter. + +If anything requests that same chunk that is in the middle of conversion, +it's mailbox queue is going to be held up, so the subsequent chunk request +will be unable to proceed. + +We delay post processing of Chunk.A() 1 "pass" by re stuffing it back into +the executor so that the mailbox ChunkQueue is now considered empty. + +This successfully fixed a reoccurring and highly reproduceable crash +for heightmaps. + +diff --git a/src/main/java/net/minecraft/server/level/ChunkProviderServer.java b/src/main/java/net/minecraft/server/level/ChunkProviderServer.java +index ff93fd88b1d30ac70ebd1130981e4aa042358f30..612a05f493981f9fb22522da4f3a5379bce4b786 100644 +--- a/src/main/java/net/minecraft/server/level/ChunkProviderServer.java ++++ b/src/main/java/net/minecraft/server/level/ChunkProviderServer.java +@@ -1019,6 +1019,7 @@ public class ChunkProviderServer extends IChunkProvider { + return super.executeNext() || execChunkTask; // Paper + } + } finally { ++ playerChunkMap.chunkLoadConversionCallbackExecutor.run(); // Paper - Add chunk load conversion callback executor to prevent deadlock due to recursion in the chunk task queue sorter + playerChunkMap.callbackExecutor.run(); + } + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java +index bb9c6e9aeb1f30af01338476ba1dd618b14124d5..80c7ff059b78f55ec9c390bd728186a94074e603 100644 +--- a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java ++++ b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java +@@ -183,6 +183,8 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + }; + // CraftBukkit end + ++ final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper ++ + // Paper start - distance maps + private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<EntityPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>(); + +@@ -1048,7 +1050,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + return Either.left(chunk); + }); + }, (runnable) -> { +- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); ++ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, () -> PlayerChunkMap.this.chunkLoadConversionCallbackExecutor.execute(runnable))); // Paper - delay running Chunk post processing until outside of the sorter to prevent a deadlock scenario when post processing causes another chunk request. + }); + + completablefuture1.thenAcceptAsync((either) -> { |