Fix various World chunk methods

- Add thread check for loadChunk
- Make isChunkGenerated use the region task queue to schedule
  to "main"
- Don't complete async chunk future if not in the owning thread
  for the chunk
This commit is contained in:
Spottedleaf 2023-03-06 14:27:02 -08:00
parent 7ca8feff63
commit 8fcf959ee3

View File

@ -21859,7 +21859,7 @@ index 2ea3778ee1348e5d06b15a2c5dc5d9bd4136dbe3..72a8e27c5ff6063d2e2b3590390b24a1
@Override @Override
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index d33476ffa49d7f6388bb227f8a57cf115a74698f..ddb59118551449b4c8855cdeaabedb08af148fff 100644 index d33476ffa49d7f6388bb227f8a57cf115a74698f..673b5dabaf3b22ea6cd31591027efc0118a44947 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -180,7 +180,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -180,7 +180,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@ -21871,7 +21871,28 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..ddb59118551449b4c8855cdeaabedb08
} }
@Override @Override
@@ -788,13 +788,14 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -361,10 +361,10 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean isChunkGenerated(int x, int z) {
// Paper start - Fix this method
- if (!Bukkit.isPrimaryThread()) {
+ if (!io.papermc.paper.util.TickThread.isTickThreadFor(this.getHandle(), x, z)) { // Folia - region threading
return java.util.concurrent.CompletableFuture.supplyAsync(() -> {
return CraftWorld.this.isChunkGenerated(x, z);
- }, world.getChunkSource().mainThreadProcessor).join();
+ }, (run) -> { io.papermc.paper.threadedregions.RegionisedServer.getInstance().taskQueue.queueChunkTask(this.getHandle(), x, z, run);}).join(); // Folia - region threading
}
ChunkAccess chunk = world.getChunkSource().getChunkAtImmediately(x, z);
if (chunk == null) {
@@ -530,6 +530,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean loadChunk(int x, int z, boolean generate) {
+ io.papermc.paper.util.TickThread.ensureTickThread(this.getHandle(), x, z, "May not sync load chunks asynchronously"); // Folia - region threading
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
warnUnsafeChunk("loading a faraway chunk", x, z); // Paper
// Paper start - Optimize this method
@@ -788,13 +789,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) { public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate) {
@ -21891,7 +21912,7 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..ddb59118551449b4c8855cdeaabedb08
BlockPos position = ((CraftBlockState) blockstate).getPosition(); BlockPos position = ((CraftBlockState) blockstate).getPosition();
net.minecraft.world.level.block.state.BlockState oldBlock = this.world.getBlockState(position); net.minecraft.world.level.block.state.BlockState oldBlock = this.world.getBlockState(position);
int flag = ((CraftBlockState) blockstate).getFlag(); int flag = ((CraftBlockState) blockstate).getFlag();
@@ -802,10 +803,10 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -802,10 +804,10 @@ public class CraftWorld extends CraftRegionAccessor implements World {
net.minecraft.world.level.block.state.BlockState newBlock = this.world.getBlockState(position); net.minecraft.world.level.block.state.BlockState newBlock = this.world.getBlockState(position);
this.world.notifyAndUpdatePhysics(position, null, oldBlock, newBlock, newBlock, flag, 512); this.world.notifyAndUpdatePhysics(position, null, oldBlock, newBlock, newBlock, flag, 512);
} }
@ -21904,7 +21925,7 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..ddb59118551449b4c8855cdeaabedb08
return false; return false;
} }
} }
@@ -878,7 +879,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -878,7 +880,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override @Override
public long getGameTime() { public long getGameTime() {
@ -21913,7 +21934,7 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..ddb59118551449b4c8855cdeaabedb08
} }
@Override @Override
@@ -1853,7 +1854,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -1853,7 +1855,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return; if (!(entity instanceof CraftEntity craftEntity) || entity.getWorld() != this || sound == null || category == null) return;
ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(CraftSound.getSoundEffect(sound)), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, this.getHandle().getRandom().nextLong()); ClientboundSoundEntityPacket packet = new ClientboundSoundEntityPacket(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(CraftSound.getSoundEffect(sound)), net.minecraft.sounds.SoundSource.valueOf(category.name()), craftEntity.getHandle(), volume, pitch, this.getHandle().getRandom().nextLong());
@ -21922,7 +21943,16 @@ index d33476ffa49d7f6388bb227f8a57cf115a74698f..ddb59118551449b4c8855cdeaabedb08
if (entityTracker != null) { if (entityTracker != null) {
entityTracker.broadcastAndSend(packet); entityTracker.broadcastAndSend(packet);
} }
@@ -2356,7 +2357,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @@ -2339,7 +2341,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
// Paper start
public java.util.concurrent.CompletableFuture<Chunk> getChunkAtAsync(int x, int z, boolean gen, boolean urgent) {
warnUnsafeChunk("getting a faraway chunk async", x, z); // Paper
- if (Bukkit.isPrimaryThread()) {
+ if (io.papermc.paper.util.TickThread.isTickThreadFor(this.getHandle(), x, z)) { // Folia - region threading
net.minecraft.world.level.chunk.LevelChunk immediate = this.world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
if (immediate != null) {
return java.util.concurrent.CompletableFuture.completedFuture(immediate.getBukkitChunk());
@@ -2356,7 +2358,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
java.util.concurrent.CompletableFuture<Chunk> ret = new java.util.concurrent.CompletableFuture<>(); java.util.concurrent.CompletableFuture<Chunk> ret = new java.util.concurrent.CompletableFuture<>();
io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> { io.papermc.paper.chunk.system.ChunkSystem.scheduleChunkLoad(this.getHandle(), x, z, gen, ChunkStatus.FULL, true, priority, (c) -> {