<commit_before>--- ../src-base/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
+++ ../src-work/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
@@ -35,6 +35,7 @@
     public final IChunkLoader field_73247_e;
     public final Long2ObjectMap<Chunk> field_73244_f = new Long2ObjectOpenHashMap(8192);
     public final WorldServer field_73251_h;
+    private Set<Long> loadingChunks = com.google.common.collect.Sets.newHashSet();
 
     public ChunkProviderServer(WorldServer p_i46838_1_, IChunkLoader p_i46838_2_, IChunkGenerator p_i46838_3_)
     {
@@ -82,20 +83,50 @@
     @Nullable
     public Chunk func_186028_c(int p_186028_1_, int p_186028_2_)
     {
-        Chunk chunk = this.func_186026_b(p_186028_1_, p_186028_2_);
+        return loadChunk(p_186028_1_, p_186028_2_, null);
+    }
 
+    @Nullable
+    public Chunk loadChunk(int p_186028_1_, int p_186028_2_, Runnable runnable)
+    {
+        Chunk chunk = this.func_186026_b(p_186028_1_, p_186028_2_);
         if (chunk == null)
         {
-            chunk = this.func_73239_e(p_186028_1_, p_186028_2_);
-
-            if (chunk != null)
+            long pos = ChunkPos.func_77272_a(p_186028_1_, p_186028_2_);
+            chunk = net.minecraftforge.common.ForgeChunkManager.fetchDormantChunk(pos, this.field_73251_h);
+            if (chunk != null || !(this.field_73247_e instanceof net.minecraft.world.chunk.storage.AnvilChunkLoader))
             {
+                if (!loadingChunks.add(pos)) net.minecraftforge.fml.common.FMLLog.bigWarning("There is an attempt to load a chunk (%d,%d) in dimension %d that is already being loaded. This will cause weird chunk breakages.", p_186028_1_, p_186028_2_, this.field_73251_h.field_73011_w.getDimension());
+                if (chunk == null) chunk = this.func_73239_e(p_186028_1_, p_186028_2_);
+
+                if (chunk != null)
+                {
                 this.field_73244_f.put(ChunkPos.func_77272_a(p_186028_1_, p_186028_2_), chunk);
                 chunk.func_76631_c();
                 chunk.func_186030_a(this, this.field_186029_c);
+                }
+
+                loadingChunks.remove(pos);
             }
+            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)
+                    {
+                        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_);
+                }
+            }
         }
 
+        // If we didn't load the chunk async and have a callback run it now
+        if (runnable != null) runnable.run();
         return chunk;
     }
 
@@ -221,6 +252,11 @@
         {
             if (!this.field_73248_b.isEmpty())
             {
+                for (ChunkPos forced : this.field_73251_h.getPersistentChunks().keySet())
+                {
+                    this.field_73248_b.remove(ChunkPos.func_77272_a(forced.field_77276_a, forced.field_77275_b));
+                }
+
                 Iterator<Long> iterator = this.field_73248_b.iterator();
 
                 for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove())
@@ -235,6 +271,11 @@
                         this.func_73243_a(chunk);
                         this.field_73244_f.remove(olong);
                         ++i;
+                        net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.func_77272_a(chunk.field_76635_g, chunk.field_76647_h), chunk);
+                        if (field_73244_f.size() == 0 && net.minecraftforge.common.ForgeChunkManager.getPersistentChunksFor(this.field_73251_h).size() == 0 && !this.field_73251_h.field_73011_w.func_186058_p().shouldLoadSpawn()){
+                            net.minecraftforge.common.DimensionManager.unloadWorld(this.field_73251_h.field_73011_w.getDimension());
+                            break;
+                        }
                     }
                 }<commit_msg>Fix async race condition on new chunks (closes #3020) (#3090)<commit_after>--- ../src-base/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
+++ ../src-work/minecraft/net/minecraft/world/gen/ChunkProviderServer.java
@@ -35,6 +35,7 @@
     public final IChunkLoader field_73247_e;
     public final Long2ObjectMap<Chunk> field_73244_f = new Long2ObjectOpenHashMap(8192);
     public final WorldServer field_73251_h;
+    private Set<Long> loadingChunks = com.google.common.collect.Sets.newHashSet();
 
     public ChunkProviderServer(WorldServer p_i46838_1_, IChunkLoader p_i46838_2_, IChunkGenerator p_i46838_3_)
     {
@@ -82,20 +83,47 @@
     @Nullable
     public Chunk func_186028_c(int p_186028_1_, int p_186028_2_)
     {
-        Chunk chunk = this.func_186026_b(p_186028_1_, p_186028_2_);
+        return loadChunk(p_186028_1_, p_186028_2_, null);
+    }
 
+    @Nullable
+    public Chunk loadChunk(int p_186028_1_, int p_186028_2_, Runnable runnable)
+    {
+        Chunk chunk = this.func_186026_b(p_186028_1_, p_186028_2_);
         if (chunk == null)
         {
-            chunk = this.func_73239_e(p_186028_1_, p_186028_2_);
-
-            if (chunk != null)
+            long pos = ChunkPos.func_77272_a(p_186028_1_, p_186028_2_);
+            chunk = net.minecraftforge.common.ForgeChunkManager.fetchDormantChunk(pos, this.field_73251_h);
+            if (chunk != null || !(this.field_73247_e instanceof net.minecraft.world.chunk.storage.AnvilChunkLoader))
             {
+                if (!loadingChunks.add(pos)) net.minecraftforge.fml.common.FMLLog.bigWarning("There is an attempt to load a chunk (%d,%d) in dimension %d that is already being loaded. This will cause weird chunk breakages.", p_186028_1_, p_186028_2_, this.field_73251_h.field_73011_w.getDimension());
+                if (chunk == null) chunk = this.func_73239_e(p_186028_1_, p_186028_2_);
+
+                if (chunk != null)
+                {
                 this.field_73244_f.put(ChunkPos.func_77272_a(p_186028_1_, p_186028_2_), chunk);
                 chunk.func_76631_c();
                 chunk.func_186030_a(this, this.field_186029_c);
+                }
+
+                loadingChunks.remove(pos);
             }
+            else
+            {
+                net.minecraft.world.chunk.storage.AnvilChunkLoader loader = (net.minecraft.world.chunk.storage.AnvilChunkLoader) this.field_73247_e;
+                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_))
+                {
+                    // 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;
+                }
+            }
         }
 
+        // If we didn't load the chunk async and have a callback run it now
+        if (runnable != null) runnable.run();
         return chunk;
     }
 
@@ -221,6 +249,11 @@
         {
             if (!this.field_73248_b.isEmpty())
             {
+                for (ChunkPos forced : this.field_73251_h.getPersistentChunks().keySet())
+                {
+                    this.field_73248_b.remove(ChunkPos.func_77272_a(forced.field_77276_a, forced.field_77275_b));
+                }
+
                 Iterator<Long> iterator = this.field_73248_b.iterator();
 
                 for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove())
@@ -235,6 +268,11 @@
                         this.func_73243_a(chunk);
                         this.field_73244_f.remove(olong);
                         ++i;
+                        net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.func_77272_a(chunk.field_76635_g, chunk.field_76647_h), chunk);
+                        if (field_73244_f.size() == 0 && net.minecraftforge.common.ForgeChunkManager.getPersistentChunksFor(this.field_73251_h).size() == 0 && !this.field_73251_h.field_73011_w.func_186058_p().shouldLoadSpawn()){
+                            net.minecraftforge.common.DimensionManager.unloadWorld(this.field_73251_h.field_73011_w.getDimension());
+                            break;
+                        }
                     }
                 }
{'fraction_non_alphanumeric': 0.10983496877787689, 'fraction_numerical': 0.10236396074933095, 'mean_word_length': 2.1670197740112993, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3524634', 'n_tokens_mistral': 3490, 'n_tokens_neox': 2948, 'n_words': 450}