check that a task is valid before executing incase it was cancelled elsewhere

also set runners in the short circuit path so we know of the pending task incase its long running
This commit is contained in:
Aikar 2018-03-17 12:58:27 -04:00
parent 7dfbe44247
commit 26b1519733
No known key found for this signature in database
GPG key ID: 401ADFC9891FAAFE

View file

@ -1,4 +1,4 @@
From 64c30d8a2caa9ff443e46f399839579d9b4517c2 Mon Sep 17 00:00:00 2001 From 2b304a51b4e740aaab398d6bd31f54da4486ef81 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co> From: Aikar <aikar@aikar.co>
Date: Fri, 16 Mar 2018 22:59:43 -0400 Date: Fri, 16 Mar 2018 22:59:43 -0400
Subject: [PATCH] Improved Async Task Scheduler Subject: [PATCH] Improved Async Task Scheduler
@ -38,10 +38,10 @@ queue if a plugin schedules lots of asynchronous tasks.
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java
new file mode 100644 new file mode 100644
index 000000000..b1efbc3e7 index 000000000..cf5aada2f
--- /dev/null --- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java +++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java
@@ -0,0 +1,151 @@ @@ -0,0 +1,161 @@
+/* +/*
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License + * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
+ * + *
@ -82,6 +82,7 @@ index 000000000..b1efbc3e7
+ +
+ private final Executor management = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder() + private final Executor management = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder()
+ .setNameFormat("Craft Scheduler Management Thread").build()); + .setNameFormat("Craft Scheduler Management Thread").build());
+ private final List<CraftTask> temp = new ArrayList<>();
+ CraftAsyncScheduler() { + CraftAsyncScheduler() {
+ super(true); + super(true);
+ } + }
@ -108,31 +109,40 @@ index 000000000..b1efbc3e7
+ } + }
+ +
+ private synchronized void runTasks(int currentTick) { + private synchronized void runTasks(int currentTick) {
+ final List<CraftTask> temp = new ArrayList<>();
+ while (!this.pending.isEmpty() && this.pending.peek().getNextRun() <= currentTick) { + while (!this.pending.isEmpty() && this.pending.peek().getNextRun() <= currentTick) {
+ CraftTask task = this.pending.remove(); + CraftTask task = this.pending.remove();
+ this.runners.put(task.getTaskId(), task); + if (executeTask(task)) {
+ this.executor.execute(new ServerSchedulerReportingWrapper(task)); + final long period = task.getPeriod();
+ final long period = task.getPeriod(); + if (period > 0) {
+ if (period > 0) { + task.setNextRun(currentTick + period);
+ task.setNextRun(currentTick + period); + temp.add(task);
+ temp.add(task); + }
+ } + }
+ } + }
+ this.pending.addAll(temp); + this.pending.addAll(temp);
+ temp.clear();
+ } + }
+ +
+ @Override + @Override
+ protected CraftTask handle(CraftTask task, final long delay) { + protected CraftTask handle(CraftTask task, final long delay) {
+ if (task.getPeriod() == -1L && delay == 0L) { + if (task.getPeriod() == -1L && delay == 0L) {
+ this.executor.execute(task); + executeTask(task);
+ return task; + } else {
+ task.setNextRun(this.currentTick + delay);
+ this.management.execute(() -> this.addTask(task));
+ } + }
+ task.setNextRun(this.currentTick + delay);
+ this.management.execute(() -> this.addTask(task));
+ return task; + return task;
+ } + }
+ +
+ private boolean executeTask(CraftTask task) {
+ if (isValid(task)) {
+ this.runners.put(task.getTaskId(), task);
+ this.executor.execute(new ServerSchedulerReportingWrapper(task));
+ return true;
+ }
+ return false;
+ }
+
+ private synchronized void addTask(CraftTask task) { + private synchronized void addTask(CraftTask task) {
+ this.pending.add(task); + this.pending.add(task);
+ } + }
@ -140,9 +150,9 @@ index 000000000..b1efbc3e7
+ @Override + @Override
+ public synchronized void cancelTasks(Plugin plugin) { + public synchronized void cancelTasks(Plugin plugin) {
+ for (Iterator<CraftTask> iterator = this.pending.iterator(); iterator.hasNext(); ) { + for (Iterator<CraftTask> iterator = this.pending.iterator(); iterator.hasNext(); ) {
+ CraftTask taskPending = iterator.next(); + CraftTask task = iterator.next();
+ if (taskPending.getTaskId() != -1 && (plugin == null || taskPending.getOwner().equals(plugin))) { + if (task.getTaskId() != -1 && (plugin == null || task.getOwner().equals(plugin))) {
+ taskPending.cancel0(); + task.cancel0();
+ iterator.remove(); + iterator.remove();
+ } + }
+ } + }