diff options
author | Wesley Wolfe <weswolf@aol.com> | 2014-02-10 09:33:20 -0600 |
---|---|---|
committer | Wesley Wolfe <weswolf@aol.com> | 2014-02-10 09:33:20 -0600 |
commit | 1113d54dae9f55db7ab65d688d62f6521d0f2bb1 (patch) | |
tree | 8ffc8bab520f27c3a81d3a3d87f3b389a0cb2dee | |
parent | ce4b13c1a5c0211e53614476c39ac6b4ad6c9572 (diff) | |
download | craftbukkit-1113d54dae9f55db7ab65d688d62f6521d0f2bb1.tar craftbukkit-1113d54dae9f55db7ab65d688d62f6521d0f2bb1.tar.gz craftbukkit-1113d54dae9f55db7ab65d688d62f6521d0f2bb1.tar.lz craftbukkit-1113d54dae9f55db7ab65d688d62f6521d0f2bb1.tar.xz craftbukkit-1113d54dae9f55db7ab65d688d62f6521d0f2bb1.zip |
Add method to forget callbacks in AsynchronousExecutor
-rw-r--r-- | src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java b/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java index 7e9efb80..81bb0d15 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java +++ b/src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java @@ -153,8 +153,14 @@ public final class AsynchronousExecutor<P, T, C, E extends Throwable> { } } + @SuppressWarnings("unchecked") T get() throws E { initSync(); + if (callbacks.isEmpty()) { + // 'this' is a placeholder to prevent callbacks from being empty during finish call + // See get method below + callbacks.add((C) this); + } finish(); return object; } @@ -171,6 +177,9 @@ public final class AsynchronousExecutor<P, T, C, E extends Throwable> { if (t != null) { throw t; } + if (callbacks.isEmpty()) { + return; + } final CallBackProvider<P, T, C, E> provider = AsynchronousExecutor.this.provider; final P parameter = this.parameter; @@ -178,6 +187,11 @@ public final class AsynchronousExecutor<P, T, C, E extends Throwable> { provider.callStage2(parameter, object); for (C callback : callbacks) { + if (callback == this) { + // 'this' is a placeholder to prevent callbacks from being empty on a get() call + // See get method above + continue; + } provider.callStage3(parameter, object, callback); } } finally { @@ -187,6 +201,17 @@ public final class AsynchronousExecutor<P, T, C, E extends Throwable> { case FINISHED: } } + + boolean drop() { + if (set(this, PENDING, FINISHED)) { + // If we succeed that variable switch, good as forgotten + tasks.remove(parameter); + return true; + } else { + // We need the async thread to finish normally to properly dispose of the task + return false; + } + } } final CallBackProvider<P, T, C, E> provider; @@ -221,6 +246,35 @@ public final class AsynchronousExecutor<P, T, C, E extends Throwable> { } /** + * This removes a particular callback from the specified parameter. + * <p> + * If no callbacks remain for a given parameter, then the {@link CallBackProvider CallBackProvider's} stages may be omitted from execution. + * Stage 3 will have no callbacks, stage 2 will be skipped unless a {@link #get(Object)} is used, and stage 1 will be avoided on a best-effort basis. + * <p> + * Subsequent calls to {@link #getSkipQueue(Object)} will always work. + * <p> + * Subsequent calls to {@link #get(Object)} might work. + * <p> + * This should always be synchronous + * @return true if no further execution for the parameter is possible, such that, no exceptions will be thrown in {@link #finishActive()} for the parameter, and {@link #get(Object)} will throw an {@link IllegalStateException}, false otherwise + * @throws IllegalStateException if parameter is not in the queue anymore + * @throws IllegalStateException if the callback was not specified for given parameter + */ + public boolean drop(P parameter, C callback) throws IllegalStateException { + final Task task = tasks.get(parameter); + if (task == null) { + throw new IllegalStateException("Unknown " + parameter); + } + if (!task.callbacks.remove(callback)) { + throw new IllegalStateException("Unknown " + callback + " for " + parameter); + } + if (task.callbacks.isEmpty()) { + return task.drop(); + } + return false; + } + + /** * This method attempts to skip the waiting period for said parameter. * <p> * This should always be synchronous. |