mirror of
https://github.com/PaperMC/Paper.git
synced 2025-03-20 14:08:57 +01:00
#891: Fix scheduler task ID overflow and duplication issues
By: Phoenix616 <max@themoep.de>
This commit is contained in:
parent
96ffc08c35
commit
71d4016a4d
2 changed files with 28 additions and 3 deletions
|
@ -14,6 +14,7 @@ import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.IntUnaryOperator;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.plugin.IllegalPluginAccessException;
|
import org.bukkit.plugin.IllegalPluginAccessException;
|
||||||
|
@ -43,10 +44,24 @@ import org.bukkit.scheduler.BukkitWorker;
|
||||||
*/
|
*/
|
||||||
public class CraftScheduler implements BukkitScheduler {
|
public class CraftScheduler implements BukkitScheduler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start ID for the counter.
|
||||||
|
*/
|
||||||
|
private static final int START_ID = 1;
|
||||||
|
/**
|
||||||
|
* Increment the {@link #ids} field and reset it to the {@link #START_ID} if it reaches {@link Integer#MAX_VALUE}
|
||||||
|
*/
|
||||||
|
private static final IntUnaryOperator INCREMENT_IDS = previous -> {
|
||||||
|
// We reached the end, go back to the start!
|
||||||
|
if (previous == Integer.MAX_VALUE) {
|
||||||
|
return START_ID;
|
||||||
|
}
|
||||||
|
return previous + 1;
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Counter for IDs. Order doesn't matter, only uniqueness.
|
* Counter for IDs. Order doesn't matter, only uniqueness.
|
||||||
*/
|
*/
|
||||||
private final AtomicInteger ids = new AtomicInteger(1);
|
private final AtomicInteger ids = new AtomicInteger(START_ID);
|
||||||
/**
|
/**
|
||||||
* Current head of linked-list. This reference is always stale, {@link CraftTask#next} is the live reference.
|
* Current head of linked-list. This reference is always stale, {@link CraftTask#next} is the live reference.
|
||||||
*/
|
*/
|
||||||
|
@ -65,7 +80,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||||
int value = Long.compare(o1.getNextRun(), o2.getNextRun());
|
int value = Long.compare(o1.getNextRun(), o2.getNextRun());
|
||||||
|
|
||||||
// If the tasks should run on the same tick they should be run FIFO
|
// If the tasks should run on the same tick they should be run FIFO
|
||||||
return value != 0 ? value : Integer.compare(o1.getTaskId(), o2.getTaskId());
|
return value != 0 ? value : Long.compare(o1.getCreatedAt(), o2.getCreatedAt());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
|
@ -453,7 +468,12 @@ public class CraftScheduler implements BukkitScheduler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private int nextId() {
|
private int nextId() {
|
||||||
return ids.incrementAndGet();
|
Validate.isTrue(runners.size() < Integer.MAX_VALUE, "There are already " + Integer.MAX_VALUE + " tasks scheduled! Cannot schedule more.");
|
||||||
|
int id;
|
||||||
|
do {
|
||||||
|
id = ids.updateAndGet(INCREMENT_IDS);
|
||||||
|
} while (runners.containsKey(id)); // Avoid generating duplicate IDs
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePending() {
|
private void parsePending() {
|
||||||
|
|
|
@ -27,6 +27,7 @@ class CraftTask implements BukkitTask, Runnable {
|
||||||
private final Consumer<BukkitTask> cTask;
|
private final Consumer<BukkitTask> cTask;
|
||||||
private final Plugin plugin;
|
private final Plugin plugin;
|
||||||
private final int id;
|
private final int id;
|
||||||
|
private final long createdAt = System.nanoTime();
|
||||||
|
|
||||||
CraftTask() {
|
CraftTask() {
|
||||||
this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
|
this(null, null, CraftTask.NO_REPEATING, CraftTask.NO_REPEATING);
|
||||||
|
@ -79,6 +80,10 @@ class CraftTask implements BukkitTask, Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
long getPeriod() {
|
long getPeriod() {
|
||||||
return period;
|
return period;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue