2021-06-11 14:02:28 +02:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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
2022-03-02 19:24:32 +01:00
that have connections across chunk boundaries occur, a recursive risk
2021-06-11 14:02:28 +02:00
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.
2022-03-02 19:24:32 +01:00
This successfully fixed a reoccurring and highly reproducible crash
2021-06-11 14:02:28 +02:00
for heightmaps.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
2022-09-01 18:51:59 +02:00
index fcc9dd6e1c54e4ca16102150aa4c12ecc7de06df..aed3da6ef2d498d3f1c9c64177bf1ba6b8157493 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
2022-09-01 18:51:59 +02:00
@@ -193,6 +193,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
2021-06-11 14:02:28 +02:00
};
// CraftBukkit end
+ final CallbackExecutor chunkLoadConversionCallbackExecutor = new CallbackExecutor(); // Paper
// Paper start - distance maps
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
2021-11-24 12:38:00 +01:00
2022-09-01 18:51:59 +02:00
@@ -1132,16 +1133,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
2022-03-02 19:08:10 +01:00
});
CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> completablefuture1 = completablefuture.thenApplyAsync((either) -> {
2022-03-02 19:24:32 +01:00
return either.mapLeft((list) -> {
2022-03-02 19:08:10 +01:00
- return (LevelChunk) list.get(list.size() / 2);
- });
- }, (runnable) -> {
2021-06-11 14:02:28 +02:00
- this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, runnable));
2022-03-02 19:08:10 +01:00
- }).thenApplyAsync((either) -> {
- return either.ifLeft((chunk) -> {
2022-03-02 19:24:32 +01:00
+ // Paper start - revert 1.18.2 diff
+ final LevelChunk chunk = (LevelChunk) list.get(list.size() / 2);
2022-03-01 05:11:35 +01:00
chunk.postProcessGeneration();
2022-03-02 19:08:10 +01:00
this.level.startTickingChunk(chunk);
2022-03-02 19:24:32 +01:00
+ return chunk;
2022-03-02 19:08:10 +01:00
});
- }, this.mainThreadExecutor);
+ }, (runnable) -> {
2022-03-02 19:24:32 +01:00
+ this.mainThreadMailbox.tell(ChunkTaskPriorityQueueSorter.message(holder, () -> ChunkMap.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.
+ }); // Paper end - revert 1.18.2 diff
2022-03-02 19:08:10 +01:00
completablefuture1.thenAcceptAsync((either) -> {
either.ifLeft((chunk) -> {
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
2022-09-01 18:51:59 +02:00
index d97b50a7a71b8bb8dcaab35ae5f03314ad6acf7e..a986051dead41f1a9f70e5e00572255e9939c4a9 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
2022-09-01 18:51:59 +02:00
@@ -992,6 +992,7 @@ public class ServerChunkCache extends ChunkSource {
2021-06-11 14:02:28 +02:00
return super.pollTask() || execChunkTask; // Paper
}
} finally {
+ chunkMap.chunkLoadConversionCallbackExecutor.run(); // Paper - Add chunk load conversion callback executor to prevent deadlock due to recursion in the chunk task queue sorter
chunkMap.callbackExecutor.run();
}
// CraftBukkit end