summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java2
-rw-r--r--src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java37
-rw-r--r--src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java17
-rw-r--r--src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java4
4 files changed, 59 insertions, 1 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
index 72938bbb..cb6dc229 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java
@@ -28,7 +28,7 @@ public class CraftCrashReport implements Callable {
for (Map.Entry<Thread, ? extends Object[]> entry : Thread.getAllStackTraces().entrySet()) {
value.append(' ').append(entry.getKey().getState().name()).append(' ').append(entry.getKey().getName()).append(": ").append(Arrays.toString(entry.getValue())).append(',');
}
- value.append('}');
+ value.append("}\n ").append(Bukkit.getScheduler().toString());
} catch (Throwable t) {
value.append("\n Failed to handle CraftCrashReport:\n");
PrintWriter writer = new PrintWriter(value);
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java
new file mode 100644
index 00000000..2899bacf
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java
@@ -0,0 +1,37 @@
+package org.bukkit.craftbukkit.scheduler;
+
+import org.bukkit.plugin.Plugin;
+
+
+class CraftAsyncDebugger {
+ private CraftAsyncDebugger next = null;
+ private final int expiry;
+ private final Plugin plugin;
+ private final Class<? extends Runnable> clazz;
+
+ CraftAsyncDebugger(final int expiry, final Plugin plugin, final Class<? extends Runnable> clazz) {
+ this.expiry = expiry;
+ this.plugin = plugin;
+ this.clazz = clazz;
+
+ }
+
+ final CraftAsyncDebugger getNextHead(final int time) {
+ CraftAsyncDebugger next, current = this;
+ while (time > current.expiry && (next = current.next) != null) {
+ current = next;
+ }
+ return current;
+ }
+
+ final CraftAsyncDebugger setNext(final CraftAsyncDebugger next) {
+ return this.next = next;
+ }
+
+ StringBuilder debugTo(final StringBuilder string) {
+ for (CraftAsyncDebugger next = this; next != null; next = next.next) {
+ string.append(plugin.getDescription().getName()).append(':').append(clazz.getName()).append('@').append(expiry).append(',');
+ }
+ return string;
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 6b70a78b..f2dbfbad 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -71,6 +71,13 @@ public class CraftScheduler implements BukkitScheduler {
private final ConcurrentHashMap<Integer, CraftTask> runners = new ConcurrentHashMap<Integer, CraftTask>();
private volatile int currentTick = -1;
private final Executor executor = Executors.newCachedThreadPool();
+ private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) {@Override StringBuilder debugTo(StringBuilder string) {return string;}};
+ private CraftAsyncDebugger debugTail = debugHead;
+ private static final int RECENT_TICKS;
+
+ static {
+ RECENT_TICKS = 30;
+ }
public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable task) {
return this.scheduleSyncDelayedTask(plugin, task, 0l);
@@ -325,6 +332,7 @@ public class CraftScheduler implements BukkitScheduler {
}
parsePending();
} else {
+ debugTail = debugTail.setNext(new CraftAsyncDebugger(currentTick + RECENT_TICKS, task.getOwner(), task.getTaskClass()));
executor.execute(task);
// We don't need to parse pending
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
@@ -339,6 +347,7 @@ public class CraftScheduler implements BukkitScheduler {
}
pending.addAll(temp);
temp.clear();
+ debugHead = debugHead.getNextHead(currentTick);
}
private void addTask(final CraftTask task) {
@@ -418,4 +427,12 @@ public class CraftScheduler implements BukkitScheduler {
}
return true;
}
+
+ @Override
+ public String toString() {
+ int debugTick = currentTick;
+ StringBuilder string = new StringBuilder("Recent tasks from ").append(debugTick - RECENT_TICKS).append('-').append(debugTick).append('{');
+ debugHead.debugTo(string);
+ return string.append('}').toString();
+ }
}
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
index 8e56766d..cfd6fb45 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
@@ -75,4 +75,8 @@ class CraftTask implements BukkitTask, Runnable {
void setNext(CraftTask next) {
this.next = next;
}
+
+ Class<? extends Runnable> getTaskClass() {
+ return task.getClass();
+ }
}