PaperMC/patches/server/0027-Properly-cancel-chunk-load-tasks-that-were-not-sched.patch
2023-06-07 22:26:06 -07:00

71 lines
3.1 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 15 May 2023 12:24:17 -0700
Subject: [PATCH] Properly cancel chunk load tasks that were not scheduled
Since the chunk load task was not scheduled, the entity/poi load
task fields will not be set, but the task complete counter
will not be adjusted. Thus, the chunk load task will not complete.
To resolve this, detect when the entity/poi tasks were not scheduled
and decrement the task complete counter in such cases.
diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java
index 1f7c146ff0b2a835c818f49da6c1f1411f26aa39..34dc2153e90a29bc9102d9497c3c53b5de15508e 100644
--- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java
+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java
@@ -25,7 +25,6 @@ import org.slf4j.Logger;
import java.lang.invoke.VarHandle;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
public final class ChunkLoadTask extends ChunkProgressionTask {
@@ -125,8 +124,12 @@ public final class ChunkLoadTask extends ChunkProgressionTask {
@Override
public void cancel() {
// must be before load task access, so we can synchronise with the writes to the fields
+ final boolean scheduled;
this.scheduler.schedulingLock.lock();
try {
+ // fix cancellation of chunk load task - must read field here, as it may be written later conucrrently -
+ // we need to know if we scheduled _before_ cancellation
+ scheduled = this.scheduled;
this.cancelled = true;
} finally {
this.scheduler.schedulingLock.unlock();
@@ -139,15 +142,26 @@ public final class ChunkLoadTask extends ChunkProgressionTask {
the chunk load task attempts to complete with a non-null value
*/
- if (this.entityLoadTask != null) {
- if (this.entityLoadTask.cancel()) {
- this.tryCompleteLoad();
+ if (scheduled) {
+ // since we scheduled, we need to cancel the tasks
+ if (this.entityLoadTask != null) {
+ if (this.entityLoadTask.cancel()) {
+ this.tryCompleteLoad();
+ }
}
- }
- if (this.poiLoadTask != null) {
- if (this.poiLoadTask.cancel()) {
- this.tryCompleteLoad();
+ if (this.poiLoadTask != null) {
+ if (this.poiLoadTask.cancel()) {
+ this.tryCompleteLoad();
+ }
}
+ } else {
+ // since nothing was scheduled, we need to decrement the task count here ourselves
+
+ // for entity load task
+ this.tryCompleteLoad();
+
+ // for poi load task
+ this.tryCompleteLoad();
}
this.loadTask.cancel();
}