From 4301dc6525fb6596bddb75a4dc915d090103d734 Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Wed, 10 Oct 2012 07:16:01 +0200 Subject: [PATCH] Add the ability to customize the worker threads. --- .../com/comphenix/protocol/Application.java | 5 ++ .../comphenix/protocol/ProtocolLibrary.java | 5 ++ .../protocol/async/AsyncListenerHandler.java | 55 +++++++++++++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/ProtocolLib/src/com/comphenix/protocol/Application.java b/ProtocolLib/src/com/comphenix/protocol/Application.java index 1ba08ce7..a4ef1376 100644 --- a/ProtocolLib/src/com/comphenix/protocol/Application.java +++ b/ProtocolLib/src/com/comphenix/protocol/Application.java @@ -17,6 +17,11 @@ package com.comphenix.protocol; +/** + * Ignore this class. + * + * @author Kristian + */ public class Application { public static void main(String[] args) { // For now, though we might consider making a proper application diff --git a/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java index 1b8a7132..ad2dab81 100644 --- a/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java +++ b/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java @@ -30,6 +30,11 @@ import com.comphenix.protocol.injector.PacketFilterManager; import com.comphenix.protocol.metrics.Statistics; import com.comphenix.protocol.reflect.compiler.BackgroundCompiler; +/** + * The main entry point for ProtocolLib. + * + * @author Kristian + */ public class ProtocolLibrary extends JavaPlugin { // There should only be one protocol manager, so we'll make it static diff --git a/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java b/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java index 86950c40..7983c2e5 100644 --- a/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java +++ b/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java @@ -13,6 +13,7 @@ import com.comphenix.protocol.events.ListeningWhitelist; import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketListener; +import com.google.common.base.Function; import com.google.common.base.Joiner; /** @@ -53,7 +54,7 @@ public class AsyncListenerHandler { // List of queued packets private ArrayBlockingQueue queuedPackets = new ArrayBlockingQueue(DEFAULT_CAPACITY); - + // List of cancelled tasks private final Set stoppedTasks = new HashSet(); private final Object stopLock = new Object(); @@ -200,7 +201,7 @@ public class AsyncListenerHandler { } /** - * Start a singler worker thread handling the asynchronous. + * Start a singler worker thread handling the asynchronous listener. */ public synchronized void start() { if (listener.getPlugin() == null) @@ -213,11 +214,55 @@ public class AsyncListenerHandler { filterManager.scheduleAsyncTask(listener.getPlugin(), new Runnable() { @Override public void run() { - String workerName = getFriendlyWorkerName(listenerLoop.getID()); + Thread thread = Thread.currentThread(); + String previousName = thread.getName(); + String workerName = getFriendlyWorkerName(listenerLoop.getID()); + // Add the friendly worker name - Thread.currentThread().setName(workerName); + thread.setName(workerName); listenerLoop.run(); + thread.setName(previousName); + } + }); + } + + /** + * Start a singler worker thread handling the asynchronous listener. + *

+ * This method is intended to allow callers to customize the thread priority + * before the worker loop is actually called. This is simpler than to + * schedule the worker threads manually. + *


+	 * listenerHandler.start(new Function<AsyncRunnable, Void>() {
+	 *     @Override
+	 *     public Void apply(@Nullable AsyncRunnable workerLoop) {
+	 *         Thread thread = Thread.currentThread();
+	 *         int prevPriority = thread.getPriority();
+	 *	       
+	 *         thread.setPriority(Thread.MIN_PRIORITY);
+	 *         workerLoop.run();
+	 *         thread.setPriority(prevPriority);
+	 *         return null;
+	 *     }
+	 *   });
+	 * }
+	 * 
+ * @param executor - a method that will execute the given listener loop. + */ + public synchronized void start(Function executor) { + if (listener.getPlugin() == null) + throw new IllegalArgumentException("Cannot start task without a valid plugin."); + if (cancelled) + throw new IllegalStateException("Cannot start a worker when the listener is closing."); + + final AsyncRunnable listenerLoop = getListenerLoop(); + final Function delegateCopy = executor; + + filterManager.scheduleAsyncTask(listener.getPlugin(), new Runnable() { + @Override + public void run() { + delegateCopy.apply(listenerLoop); } }); } @@ -300,7 +345,7 @@ public class AsyncListenerHandler { stop(); // May happen if another thread is doing something similar to "setWorkers" - if ((System.currentTimeMillis() - time) > 1000) + if ((System.currentTimeMillis() - time) > 50) throw new RuntimeException("Failed to set worker count."); } }