Bypass chunk future chain when processing loads and getChunk called. (#7697)

This commit is contained in:
covers1624 authored and GitHub committed 2021-07-16 17:26:45 -07:00
1 parent dd228a9ac1
commit 022482a3bd
3 files changed
+33 -1

No files matched your search

@@ -1,5 +1,13 @@
--- a/net/minecraft/world/server/ChunkHolder.java
+++ b/net/minecraft/world/server/ChunkHolder.java
@@ -61,6 +_,7 @@
private final ChunkHolder.IPlayerProvider field_219328_w;
private boolean field_219329_x;
private boolean field_244384_x;
+ Chunk currentlyLoading; //Forge - Used to bypass future chain when loading chunks.
public ChunkHolder(ChunkPos p_i50716_1_, int p_i50716_2_, WorldLightManager p_i50716_3_, ChunkHolder.IListener p_i50716_4_, ChunkHolder.IPlayerProvider p_i50716_5_) {
this.field_219319_n = p_i50716_1_;
@@ -204,7 +_,7 @@
}
@@ -8,11 +8,23 @@
}
this.func_219229_a(p_219185_5_);
@@ -601,6 +_,7 @@
@@ -581,6 +_,8 @@
chunk.func_217318_w();
if (this.field_219254_h.add(chunkpos.func_201841_a())) {
chunk.func_177417_c(true);
+ try {
+ p_219200_1_.currentlyLoading = chunk; //Forge - bypass the future chain when getChunk is called, this prevents deadlocks.
this.field_219255_i.func_147448_a(chunk.func_177434_r().values());
List<Entity> list = null;
ClassInheritanceMultiMap<Entity>[] aclassinheritancemultimap = chunk.func_177429_s();
@@ -601,6 +_,10 @@
if (list != null) {
list.forEach(chunk::func_76622_b);
}
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkEvent.Load(chunk));
+ } finally {
+ p_219200_1_.currentlyLoading = null;//Forge - Stop bypassing the future chain.
+ }
}
return chunk;
@@ -1,5 +1,17 @@
--- a/net/minecraft/world/server/ServerChunkProvider.java
+++ b/net/minecraft/world/server/ServerChunkProvider.java
@@ -125,6 +_,11 @@
}
}
+ ChunkHolder chunkholder = this.func_217213_a(i);
+ if (chunkholder != null && chunkholder.currentlyLoading != null) {
+ return chunkholder.currentlyLoading; //Forge - If the requested chunk is loading, bypass the future chain to prevent a deadlock.
+ }
+
iprofiler.func_230035_c_("getChunkCacheMiss");
CompletableFuture<Either<IChunk, ChunkHolder.IChunkLoadingError>> completablefuture = this.func_217233_c(p_212849_1_, p_212849_2_, p_212849_3_, p_212849_4_);
this.field_217243_i.func_213161_c(completablefuture::isDone);
@@ -353,7 +_,7 @@
if (optional1.isPresent()) {
Chunk chunk = optional1.get();