543 lines
23 KiB
Diff
543 lines
23 KiB
Diff
From 729f4f03b190546f3e3de4cd5abf38bd8cd50409 Mon Sep 17 00:00:00 2001
|
|
From: Poweruser <poweruser.rs@hotmail.com>
|
|
Date: Sat, 28 May 2016 21:51:43 +0200
|
|
Subject: [PATCH] Combine different CachedThreadPools into one
|
|
|
|
|
|
diff --git a/src/main/java/net/frozenorb/NamePriorityThreadFactory.java b/src/main/java/net/frozenorb/NamePriorityThreadFactory.java
|
|
index e0a6e76ed..bc084b61d 100644
|
|
--- a/src/main/java/net/frozenorb/NamePriorityThreadFactory.java
|
|
+++ b/src/main/java/net/frozenorb/NamePriorityThreadFactory.java
|
|
@@ -1,5 +1,9 @@
|
|
package net.frozenorb;
|
|
|
|
+import java.lang.ref.WeakReference;
|
|
+import java.util.Iterator;
|
|
+import java.util.Queue;
|
|
+import java.util.concurrent.ConcurrentLinkedQueue;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.ThreadFactory;
|
|
|
|
@@ -8,29 +12,36 @@ public class NamePriorityThreadFactory implements ThreadFactory {
|
|
private int idCounter = 0;
|
|
private String name = "mSpigotThread";
|
|
private boolean isDaemon = false;
|
|
+ private Queue<WeakReference<Thread>> createdThreadList;
|
|
|
|
public NamePriorityThreadFactory(int priority) {
|
|
this.priority = Math.min(Math.max(priority, Thread.MIN_PRIORITY), Thread.MAX_PRIORITY);
|
|
}
|
|
|
|
- public NamePriorityThreadFactory(int priority, boolean daemon) {
|
|
+ public NamePriorityThreadFactory(int priority, String name) {
|
|
this(priority);
|
|
- this.isDaemon = daemon;
|
|
+ this.name = name;
|
|
}
|
|
|
|
- public NamePriorityThreadFactory(int priority, String name) {
|
|
- this(priority);
|
|
+ public NamePriorityThreadFactory(String name) {
|
|
+ this(Thread.NORM_PRIORITY);
|
|
this.name = name;
|
|
}
|
|
|
|
- public NamePriorityThreadFactory(int priority, String name, boolean daemon) {
|
|
- this(priority, name);
|
|
+ public NamePriorityThreadFactory setDaemon(boolean daemon) {
|
|
this.isDaemon = daemon;
|
|
+ return this;
|
|
}
|
|
|
|
- public NamePriorityThreadFactory(String name) {
|
|
- this(Thread.NORM_PRIORITY);
|
|
- this.name = name;
|
|
+ public NamePriorityThreadFactory setLogThreads(boolean log) {
|
|
+ if(log) {
|
|
+ if(this.createdThreadList == null) {
|
|
+ this.createdThreadList = new ConcurrentLinkedQueue<WeakReference<Thread>>();
|
|
+ }
|
|
+ } else {
|
|
+ this.createdThreadList = null;
|
|
+ }
|
|
+ return this;
|
|
}
|
|
|
|
@Override
|
|
@@ -39,7 +50,32 @@ public class NamePriorityThreadFactory implements ThreadFactory {
|
|
thread.setPriority(this.priority);
|
|
thread.setName(this.name + "-" + String.valueOf(idCounter));
|
|
thread.setDaemon(this.isDaemon);
|
|
+ if(this.createdThreadList != null) {
|
|
+ this.createdThreadList.add(new WeakReference<Thread>(thread));
|
|
+ }
|
|
idCounter++;
|
|
return thread;
|
|
}
|
|
+
|
|
+ public int getActiveCount() {
|
|
+ if(this.createdThreadList != null) {
|
|
+ Iterator<WeakReference<Thread>> iter = this.createdThreadList.iterator();
|
|
+ int count = 0;
|
|
+ while(iter.hasNext()) {
|
|
+ WeakReference<Thread> ref = iter.next();
|
|
+ Thread t = ref.get();
|
|
+ if(t == null) {
|
|
+ iter.remove();
|
|
+ } else if(t.isAlive()) {
|
|
+ count++;
|
|
+ }
|
|
+ }
|
|
+ return count;
|
|
+ }
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ public Queue<WeakReference<Thread>> getThreadList() {
|
|
+ return this.createdThreadList;
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/frozenorb/ThreadingManager.java b/src/main/java/net/frozenorb/ThreadingManager.java
|
|
index 0ee93dbf0..e0b3c38f2 100644
|
|
--- a/src/main/java/net/frozenorb/ThreadingManager.java
|
|
+++ b/src/main/java/net/frozenorb/ThreadingManager.java
|
|
@@ -4,10 +4,17 @@ import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
+import java.lang.ref.WeakReference;
|
|
import java.util.ArrayDeque;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Iterator;
|
|
+import java.util.Queue;
|
|
import java.util.concurrent.Callable;
|
|
+import java.util.concurrent.ConcurrentLinkedDeque;
|
|
+import java.util.concurrent.Executor;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
+import java.util.concurrent.Future;
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
import java.util.concurrent.ScheduledFuture;
|
|
import java.util.concurrent.TimeUnit;
|
|
@@ -21,42 +28,81 @@ import net.minecraft.server.NBTTagCompound;
|
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
+import org.spigotmc.SpigotConfig;
|
|
|
|
public class ThreadingManager {
|
|
|
|
private final Logger log = LogManager.getLogger();
|
|
- private ExecutorService nbtFileService = Executors.newSingleThreadExecutor(new NamePriorityThreadFactory(Thread.NORM_PRIORITY - 2, "mSpigot_NBTFileSaver"));
|
|
private static ThreadingManager instance;
|
|
private PathSearchThrottlerThread pathSearchThrottler;
|
|
private ScheduledExecutorService timerService = Executors.newScheduledThreadPool(1, new NamePriorityThreadFactory(Thread.NORM_PRIORITY + 2, "mSpigot_TimerService"));
|
|
private TickCounter tickCounter = new TickCounter();
|
|
+ private NamePriorityThreadFactory cachedThreadPoolFactory;
|
|
+ private ExecutorService cachedThreadPool;
|
|
|
|
private ScheduledFuture<Object> tickTimerTask;
|
|
private TickTimer tickTimerObject;
|
|
private static int timerDelay = 45;
|
|
|
|
+ private TaskQueueWorker nbtFiles;
|
|
+ private TaskQueueWorker headConversions;
|
|
+
|
|
public ThreadingManager() {
|
|
instance = this;
|
|
this.pathSearchThrottler = new PathSearchThrottlerThread(2);
|
|
this.timerService.scheduleAtFixedRate(this.tickCounter, 1, 1000, TimeUnit.MILLISECONDS);
|
|
this.tickTimerObject = new TickTimer();
|
|
+ this.cachedThreadPoolFactory = new NamePriorityThreadFactory(Thread.currentThread().getPriority() - 1, "mSpigot_Async-Executor").setLogThreads(true).setDaemon(true);
|
|
+ this.cachedThreadPool = Executors.newCachedThreadPool(this.cachedThreadPoolFactory);
|
|
+ this.nbtFiles = this.createTaskQueueWorker();
|
|
+ this.headConversions = this.createTaskQueueWorker();
|
|
}
|
|
|
|
public void shutdown() {
|
|
this.pathSearchThrottler.shutdown();
|
|
- this.nbtFileService.shutdown();
|
|
this.timerService.shutdown();
|
|
- while(!this.nbtFileService.isTerminated()) {
|
|
+ this.cachedThreadPool.shutdown();
|
|
+ while((this.nbtFiles.isActive()) && !this.cachedThreadPool.isTerminated()) {
|
|
try {
|
|
- if(!this.nbtFileService.awaitTermination(3, TimeUnit.MINUTES)) {
|
|
- log.warn("mSpigot is still waiting for NBT Files to be saved.");
|
|
- }
|
|
+ this.cachedThreadPool.awaitTermination(10, TimeUnit.SECONDS);
|
|
+ log.warn("mSpigot is still waiting for NBT files to be written to disk. " + this.nbtFiles.getTaskCount() + " to go...");
|
|
} catch(InterruptedException e) {}
|
|
}
|
|
+ if(!this.cachedThreadPool.isTerminated()) {
|
|
+ this.cachedThreadPool.shutdownNow();
|
|
+ try {
|
|
+ this.cachedThreadPool.awaitTermination(10L, TimeUnit.SECONDS);
|
|
+ } catch (InterruptedException e) {
|
|
+ e.printStackTrace();
|
|
+ }
|
|
+ if(SpigotConfig.logRemainingAsyncThreadsDuringShutdown && this.cachedThreadPoolFactory.getActiveCount() > 0) {
|
|
+ log.warn("mSpigot is still waiting for " + this.cachedThreadPoolFactory.getActiveCount() + " async threads to finish.");
|
|
+ Queue<WeakReference<Thread>> queue = this.cachedThreadPoolFactory.getThreadList();
|
|
+ Iterator<WeakReference<Thread>> iter = null;
|
|
+ if(queue != null) {
|
|
+ System.out.println("== List of async threads that did not terminate on their own == ");
|
|
+ iter = queue.iterator();
|
|
+ }
|
|
+ while(iter != null && iter.hasNext()) {
|
|
+ WeakReference<Thread> ref = iter.next();
|
|
+ Thread t = ref.get();
|
|
+ if(t == null) {
|
|
+ iter.remove();
|
|
+ } else if (t.isAlive()) {
|
|
+ StackTraceElement[] e = t.getStackTrace();
|
|
+ System.out.println(t.getName() + " - " + t.getState().toString());
|
|
+ for(StackTraceElement et: e) {
|
|
+ System.out.println(et.toString());
|
|
+ }
|
|
+ System.out.println("========================== ");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
public static void saveNBTPlayerDataStatic(PlayerDataSaveJob savejob) {
|
|
- instance.nbtFileService.execute(savejob);
|
|
+ instance.nbtFiles.queueTask(savejob);
|
|
}
|
|
|
|
public static void saveNBTFileStatic(NBTTagCompound compound, File file) {
|
|
@@ -64,7 +110,7 @@ public class ThreadingManager {
|
|
}
|
|
|
|
public void saveNBTFile(NBTTagCompound compound, File file) {
|
|
- this.nbtFileService.execute(new NBTFileSaver(compound, file));
|
|
+ this.nbtFiles.queueTask(new NBTFileSaver(compound, file));
|
|
}
|
|
|
|
private class NBTFileSaver implements Runnable {
|
|
@@ -176,4 +222,79 @@ public class ThreadingManager {
|
|
public static void addWorldStatsTask(WorldStatsTask task) {
|
|
instance.timerService.schedule(task, 2, TimeUnit.SECONDS);
|
|
}
|
|
+
|
|
+ public static void execute(Runnable runnable) {
|
|
+ instance.cachedThreadPool.execute(runnable);
|
|
+ }
|
|
+
|
|
+ public static Future<?> submit(Runnable runnable) {
|
|
+ return instance.cachedThreadPool.submit(runnable);
|
|
+ }
|
|
+
|
|
+ public static Future<?> submit(Callable<?> callable) {
|
|
+ return instance.cachedThreadPool.submit(callable);
|
|
+ }
|
|
+
|
|
+ public static void queueHeadConversion(Runnable runnable) {
|
|
+ instance.headConversions.queueTask(runnable);
|
|
+ }
|
|
+
|
|
+ public static TaskQueueWorker createTaskQueue() {
|
|
+ return instance.createTaskQueueWorker();
|
|
+ }
|
|
+
|
|
+ public TaskQueueWorker createTaskQueueWorker() {
|
|
+ return new TaskQueueWorker(this.cachedThreadPool);
|
|
+ }
|
|
+
|
|
+ public class TaskQueueWorker implements Runnable {
|
|
+
|
|
+ private ConcurrentLinkedDeque<Runnable> taskQueue = new ConcurrentLinkedDeque<Runnable>();
|
|
+ private ExecutorService service;
|
|
+ private volatile boolean isActive = false;
|
|
+
|
|
+ public TaskQueueWorker(ExecutorService service) {
|
|
+ this.service = service;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void run() {
|
|
+ Runnable task = null;
|
|
+ while(this.isActive = ((task = this.taskQueue.pollFirst()) != null)) {
|
|
+ try {
|
|
+ task.run();
|
|
+ } catch (Exception e) {
|
|
+ log.error("Thread " + Thread.currentThread().getName() + " encountered an exception: " + e.getMessage(), e);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void queueTask(Runnable runnable) {
|
|
+ this.taskQueue.addLast(runnable);
|
|
+ if(!this.isActive) {
|
|
+ this.isActive = true;
|
|
+ this.service.execute(this);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public boolean isActive() {
|
|
+ if(!this.isActive && !this.taskQueue.isEmpty()) {
|
|
+ this.isActive = true;
|
|
+ this.service.execute(this);
|
|
+ }
|
|
+ return this.isActive;
|
|
+ }
|
|
+
|
|
+ public int getTaskCount() {
|
|
+ int count = this.taskQueue.size();
|
|
+ if(this.isActive) {
|
|
+ count++;
|
|
+ }
|
|
+ return count;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static Executor getCommonThreadPool() {
|
|
+ return instance.cachedThreadPool;
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
|
|
index 5051a3f7d..ac8e05f89 100644
|
|
--- a/src/main/java/net/minecraft/server/ItemStack.java
|
|
+++ b/src/main/java/net/minecraft/server/ItemStack.java
|
|
@@ -18,6 +18,8 @@ import org.bukkit.entity.Player;
|
|
import org.bukkit.event.world.StructureGrowEvent;
|
|
// CraftBukkit end
|
|
|
|
+import net.frozenorb.ThreadingManager; // Poweruser
|
|
+
|
|
public final class ItemStack {
|
|
|
|
public static final DecimalFormat a = new DecimalFormat("#.###");
|
|
@@ -246,7 +248,7 @@ public final class ItemStack {
|
|
}
|
|
|
|
final String finalOwner = owner;
|
|
- TileEntitySkull.executor.execute( new Runnable()
|
|
+ ThreadingManager.queueHeadConversion(new Runnable() // Poweruser
|
|
{
|
|
@Override
|
|
public void run()
|
|
diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java
|
|
index 8d24d4563..d88181373 100644
|
|
--- a/src/main/java/net/minecraft/server/LoginListener.java
|
|
+++ b/src/main/java/net/minecraft/server/LoginListener.java
|
|
@@ -16,6 +16,14 @@ import net.minecraft.util.org.apache.commons.lang3.Validate;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
+// Pweruser start
|
|
+import java.util.concurrent.Executor;
|
|
+import java.util.concurrent.ExecutorService;
|
|
+import java.util.concurrent.Executors;
|
|
+import net.frozenorb.NamePriorityThreadFactory;
|
|
+import net.frozenorb.ThreadingManager;
|
|
+// Poweruser end
|
|
+
|
|
public class LoginListener implements PacketLoginInListener {
|
|
|
|
private static final AtomicInteger b = new AtomicInteger(0);
|
|
@@ -140,7 +148,7 @@ public class LoginListener implements PacketLoginInListener {
|
|
this.g = EnumProtocolState.KEY;
|
|
this.networkManager.handle(new PacketLoginOutEncryptionBegin(this.j, this.server.K().getPublic(), this.e), new GenericFutureListener[0]);
|
|
} else {
|
|
- (new ThreadPlayerLookupUUID(this, "User Authenticator #" + b.incrementAndGet())).start(); // Spigot
|
|
+ ThreadingManager.execute(new ThreadPlayerLookupUUID(this)); // Poweruser
|
|
}
|
|
}
|
|
|
|
@@ -154,7 +162,7 @@ public class LoginListener implements PacketLoginInListener {
|
|
this.loginKey = packetlogininencryptionbegin.a(privatekey);
|
|
this.g = EnumProtocolState.AUTHENTICATING;
|
|
this.networkManager.a(this.loginKey);
|
|
- (new ThreadPlayerLookupUUID(this, "User Authenticator #" + b.incrementAndGet())).start();
|
|
+ ThreadingManager.execute(new ThreadPlayerLookupUUID(this)); // Poweruser
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PacketPlayInChat.java b/src/main/java/net/minecraft/server/PacketPlayInChat.java
|
|
index d419f0f71..6146e7a70 100644
|
|
--- a/src/main/java/net/minecraft/server/PacketPlayInChat.java
|
|
+++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java
|
|
@@ -2,6 +2,8 @@ package net.minecraft.server;
|
|
|
|
import java.io.IOException; // CraftBukkit
|
|
|
|
+import net.frozenorb.ThreadingManager; // Poweruser
|
|
+
|
|
public class PacketPlayInChat extends Packet {
|
|
|
|
private String message;
|
|
@@ -44,13 +46,11 @@ public class PacketPlayInChat extends Packet {
|
|
// CraftBukkit end
|
|
|
|
// Spigot Start
|
|
- private static final java.util.concurrent.ExecutorService executors = java.util.concurrent.Executors.newCachedThreadPool(
|
|
- new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon( true ).setNameFormat( "Async Chat Thread - #%d" ).build() );
|
|
public void handle(final PacketListener packetlistener)
|
|
{
|
|
if ( a() )
|
|
{
|
|
- executors.submit( new Runnable()
|
|
+ ThreadingManager.submit( new Runnable() // Poweruser
|
|
{
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java b/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java
|
|
index fca32adf9..a28c9f6fb 100644
|
|
--- a/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java
|
|
+++ b/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java
|
|
@@ -12,12 +12,11 @@ import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
|
import org.bukkit.event.player.PlayerPreLoginEvent;
|
|
// CraftBukkit end
|
|
|
|
-class ThreadPlayerLookupUUID extends Thread {
|
|
+class ThreadPlayerLookupUUID implements Runnable { // Poweruser
|
|
|
|
final LoginListener a;
|
|
|
|
- ThreadPlayerLookupUUID(LoginListener loginlistener, String s) {
|
|
- super(s);
|
|
+ ThreadPlayerLookupUUID(LoginListener loginlistener) { // Poweruser
|
|
this.a = loginlistener;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/TileEntitySkull.java b/src/main/java/net/minecraft/server/TileEntitySkull.java
|
|
index 1796a56fc..227d345e9 100644
|
|
--- a/src/main/java/net/minecraft/server/TileEntitySkull.java
|
|
+++ b/src/main/java/net/minecraft/server/TileEntitySkull.java
|
|
@@ -18,17 +18,14 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
import net.minecraft.util.com.mojang.authlib.Agent;
|
|
// Spigot end
|
|
|
|
+import net.frozenorb.ThreadingManager; // Poweruser
|
|
+
|
|
public class TileEntitySkull extends TileEntity {
|
|
|
|
private int a;
|
|
private int i;
|
|
private GameProfile j = null;
|
|
// Spigot start
|
|
- public static final Executor executor = Executors.newFixedThreadPool(3,
|
|
- new ThreadFactoryBuilder()
|
|
- .setNameFormat("Head Conversion Thread - %1$d")
|
|
- .build()
|
|
- );
|
|
public static final Cache<String, GameProfile> skinCache = CacheBuilder.newBuilder()
|
|
.maximumSize( 5000 )
|
|
.expireAfterAccess( 60, TimeUnit.MINUTES )
|
|
@@ -122,7 +119,7 @@ public class TileEntitySkull extends TileEntity {
|
|
// Spigot start - Handle async
|
|
final String name = this.j.getName();
|
|
setSkullType( 0 ); // Work around a client bug
|
|
- executor.execute(new Runnable() {
|
|
+ ThreadingManager.queueHeadConversion(new Runnable() { // Poweruser
|
|
@Override
|
|
public void run() {
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 3b42cbecc..609fe32ae 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -40,6 +40,8 @@ import org.bukkit.event.weather.ThunderChangeEvent;
|
|
// Poweruser start
|
|
import net.frozenorb.LightingUpdater;
|
|
import net.frozenorb.WeakChunkCache;
|
|
+import net.frozenorb.ThreadingManager;
|
|
+import net.frozenorb.ThreadingManager.TaskQueueWorker;
|
|
// Poweruser end
|
|
|
|
public abstract class World implements IBlockAccess {
|
|
@@ -128,16 +130,9 @@ public abstract class World implements IBlockAccess {
|
|
public static boolean haveWeSilencedAPhysicsCrash;
|
|
public static String blockLocation;
|
|
public List<TileEntity> triggerHoppersList = new ArrayList<TileEntity>(); // Spigot, When altHopperTicking, tile entities being added go through here.
|
|
- // Poweruser start - only one thread, and with lower priority. Instead of one for each world
|
|
- private static ExecutorService lightingExecutor; // PaperSpigot - Asynchronous lighting updates
|
|
+ // Poweruser start
|
|
private LightingUpdater lightingUpdater = new LightingUpdater();
|
|
-
|
|
- public static ExecutorService getLightingExecutor() {
|
|
- if(lightingExecutor == null) {
|
|
- lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setPriority(Thread.NORM_PRIORITY - 1).setNameFormat("PaperSpigot - Lighting Thread").build());
|
|
- }
|
|
- return lightingExecutor;
|
|
- }
|
|
+ private TaskQueueWorker lightingQueue = ThreadingManager.createTaskQueue();
|
|
// Poweruser end
|
|
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<Explosion.CacheKey, Float>(); // PaperSpigot - Optimize explosions
|
|
|
|
@@ -2672,7 +2667,7 @@ public abstract class World implements IBlockAccess {
|
|
}
|
|
|
|
// Poweruser start
|
|
- getLightingExecutor().submit(new Runnable() {
|
|
+ this.lightingQueue.queueTask(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
|
index e32bcb181..b4258807e 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
|
@@ -14,6 +14,8 @@ import org.bukkit.inventory.meta.SkullMeta;
|
|
|
|
import com.google.common.collect.ImmutableMap.Builder;
|
|
|
|
+import net.frozenorb.ThreadingManager; // Poweruser
|
|
+
|
|
@DelegateDeserialization(SerializableMeta.class)
|
|
class CraftMetaSkull extends CraftMetaItem implements SkullMeta {
|
|
static final ItemMetaKey SKULL_OWNER = new ItemMetaKey("SkullOwner", "skull-owner");
|
|
@@ -56,7 +58,7 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta {
|
|
// Spigot start - do an async lookup of the profile.
|
|
// Unfortunately there is not way to refresh the holding
|
|
// inventory, so that responsibility is left to the user.
|
|
- net.minecraft.server.TileEntitySkull.executor.execute( new Runnable()
|
|
+ ThreadingManager.queueHeadConversion(new Runnable() // Poweruser
|
|
{
|
|
@Override
|
|
public void run()
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
index 93d8d4248..361d39663 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
|
@@ -14,6 +14,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
import java.util.logging.Level;
|
|
|
|
+import net.frozenorb.ThreadingManager; // Poweruser
|
|
+
|
|
import org.apache.commons.lang.Validate;
|
|
import org.bukkit.plugin.IllegalPluginAccessException;
|
|
import org.bukkit.plugin.Plugin;
|
|
@@ -72,7 +74,7 @@ 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(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build()); // Spigot
|
|
+ private final Executor executor = ThreadingManager.getCommonThreadPool(); // Poweruser
|
|
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;
|
|
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
|
index 50f16bee4..5bbe73ad3 100644
|
|
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
|
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
|
@@ -408,6 +408,11 @@ public class SpigotConfig
|
|
}
|
|
}
|
|
|
|
+ public static boolean logRemainingAsyncThreadsDuringShutdown;
|
|
+ private static void logRemainingAsyncThreadsDuringShutdown() {
|
|
+ logRemainingAsyncThreadsDuringShutdown = getBoolean( "settings.logRemainingAsyncThreadsDuringShutdown" , true);
|
|
+ }
|
|
+
|
|
private static void powertpsCommand()
|
|
{
|
|
commands.put( "tps2", new net.frozenorb.command.TPSCommand( "tps2" ) );
|
|
--
|
|
2.13.3
|
|
|