Fix async race condition on new chunks (closes #3020) (#3090)

This patch fixes a race condition that sometimes caused a just generated chunk
to be generated a second time.  In some this caused generated structures to
appear incomplete such as in Issue #3020 when the second generated version
effectively overwrote the original version of the chunk.

This patch ensures when ProvideChunk calls LoadChunk synchronously we always
attempt to load the chunk (if not cached) thus avoid the race condition without
changing the logic for async loading for chunks already saved to disk.

Thus this should retain the async functionality from PR #2946 while preventing
generation issues caused by the race condition.
This commit is contained in:
Terrence Ezrol 2016-07-21 18:51:45 -04:00 committed by LexManos
parent b7739ffc71
commit cc0e6a1825

View file

@ -8,7 +8,7 @@
public ChunkProviderServer(WorldServer p_i46838_1_, IChunkLoader p_i46838_2_, IChunkGenerator p_i46838_3_)
{
@@ -82,20 +83,50 @@
@@ -82,20 +83,47 @@
@Nullable
public Chunk func_186028_c(int p_186028_1_, int p_186028_2_)
{
@ -44,16 +44,13 @@
+ else
+ {
+ net.minecraft.world.chunk.storage.AnvilChunkLoader loader = (net.minecraft.world.chunk.storage.AnvilChunkLoader) this.field_73247_e;
+
+ // We can only use the queue for already generated chunks
+ if (loader.chunkExists(this.field_73251_h, p_186028_1_, p_186028_2_))
+ if (runnable == null)
+ chunk = net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(this.field_73251_h, loader, this, p_186028_1_, p_186028_2_);
+ else if (loader.chunkExists(this.field_73251_h, p_186028_1_, p_186028_2_))
+ {
+ if (runnable != null)
+ {
+ net.minecraftforge.common.chunkio.ChunkIOExecutor.queueChunkLoad(this.field_73251_h, loader, this, p_186028_1_, p_186028_2_, runnable);
+ return null;
+ }
+ else chunk = net.minecraftforge.common.chunkio.ChunkIOExecutor.syncChunkLoad(this.field_73251_h, loader, this, p_186028_1_, p_186028_2_);
+ // We can only use the async queue for already generated chunks
+ net.minecraftforge.common.chunkio.ChunkIOExecutor.queueChunkLoad(this.field_73251_h, loader, this, p_186028_1_, p_186028_2_, runnable);
+ return null;
+ }
+ }
}
@ -63,7 +60,7 @@
return chunk;
}
@@ -221,6 +252,11 @@
@@ -221,6 +249,11 @@
{
if (!this.field_73248_b.isEmpty())
{
@ -75,7 +72,7 @@
Iterator<Long> iterator = this.field_73248_b.iterator();
for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove())
@@ -235,6 +271,11 @@
@@ -235,6 +268,11 @@
this.func_73243_a(chunk);
this.field_73244_f.remove(olong);
++i;