From debf8c4d889426da298130f637f0c31535f22763 Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Thu, 4 Oct 2012 06:23:27 +0200 Subject: [PATCH] Create the worker ID before it is run. In addition, we'll prevent reuse of worker objects. --- .../protocol/async/AsyncListenerHandler.java | 26 +++++++++++++------ .../protocol/async/AsyncRunnable.java | 6 +++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java b/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java index 8e729875..87c09e26 100644 --- a/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java +++ b/ProtocolLib/src/com/comphenix/protocol/async/AsyncListenerHandler.java @@ -135,8 +135,9 @@ public class AsyncListenerHandler { public AsyncRunnable getListenerLoop() { return new AsyncRunnable() { - private final AtomicBoolean running = new AtomicBoolean(); - private volatile int id; + private final AtomicBoolean firstRun = new AtomicBoolean(); + private final AtomicBoolean finished = new AtomicBoolean(); + private final int id = nextID.incrementAndGet(); @Override public int getID() { @@ -146,18 +147,21 @@ public class AsyncListenerHandler { @Override public void run() { // Careful now - if (running.compareAndSet(false, true)) { - id = nextID.incrementAndGet(); + if (firstRun.compareAndSet(false, true)) { listenerLoop(id); synchronized (stopLock) { stoppedTasks.remove(id); stopLock.notifyAll(); - running.set(false); + finished.set(true); } } else { - throw new IllegalStateException( + if (finished.get()) + throw new IllegalStateException( + "This listener has already been run. Create a new instead."); + else + throw new IllegalStateException( "This listener loop has already been started. Create a new instead."); } } @@ -165,7 +169,7 @@ public class AsyncListenerHandler { @Override public boolean stop() throws InterruptedException { synchronized (stopLock) { - if (!running.get()) + if (!isRunning()) return false; stoppedTasks.add(id); @@ -175,6 +179,7 @@ public class AsyncListenerHandler { queuedPackets.offer(WAKEUP_PACKET); } + finished.set(true); waitForStops(); return true; } @@ -182,7 +187,12 @@ public class AsyncListenerHandler { @Override public boolean isRunning() { - return running.get(); + return firstRun.get() && !finished.get(); + } + + @Override + public boolean isFinished() { + return finished.get(); } }; } diff --git a/ProtocolLib/src/com/comphenix/protocol/async/AsyncRunnable.java b/ProtocolLib/src/com/comphenix/protocol/async/AsyncRunnable.java index 7e56a6b6..2c0004d9 100644 --- a/ProtocolLib/src/com/comphenix/protocol/async/AsyncRunnable.java +++ b/ProtocolLib/src/com/comphenix/protocol/async/AsyncRunnable.java @@ -26,4 +26,10 @@ public interface AsyncRunnable extends Runnable { * @return TRUE if we're running, FALSE otherwise. */ public boolean isRunning(); + + /** + * Determine if this runnable has already run its course. + * @return TRUE if it has been stopped, FALSE otherwise. + */ + boolean isFinished(); }