X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fnet%2Fpterodactylus%2Ffcp%2Fhighlevel%2FHighLevelCallback.java;h=7dc55dfc90aa753f80f5567d176fd3c82ac39227;hb=bf0b6fe3af98f1c31895190bc54d017b623acd2e;hp=b43a8ccd9709cfb482b29a24cdadf59a4bf65517;hpb=460b437b16e31ccc70c8b97818dbbae0a94c8f76;p=jFCPlib.git diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java b/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java index b43a8cc..7dc55df 100644 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java @@ -30,23 +30,29 @@ import java.util.List; * @param * The type of the high-level operation result * @author David ‘Bombe’ Roden <bombe@freenetproject.org> - * @version $Id$ */ public class HighLevelCallback { /** Object used for synchronization. */ - private final Object syncObject = new Object(); + protected final Object syncObject = new Object(); /** The list of callback listeners. */ private final List> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList>()); + /** Whether the result is complete. */ + protected boolean resultComplete = false; + /** The result of the operation. */ private R result = null; /** * Package-private construtor. + * + * @param result + * The result of the operation */ - HighLevelCallback() { + HighLevelCallback(R result) { + this.result = result; } /** @@ -77,15 +83,17 @@ public class HighLevelCallback { } /** - * Notifies all listeners that the result of the operation is now known. + * Notifies all listeners that the result of the operation is now known. As + * soon as a listener was notified it will be removed from the list of + * listeners! * * @see HighLevelCallbackListener#gotResult(HighLevelCallback) */ private synchronized void fireGotResult() { for (HighLevelCallbackListener highLevelCallbackListener: highLevelCallbackListeners) { - highLevelCallbackListeners.remove(highLevelCallbackListener); highLevelCallbackListener.gotResult(this); } + highLevelCallbackListeners.clear(); } /** @@ -97,7 +105,7 @@ public class HighLevelCallback { */ public boolean isDone() { synchronized (syncObject) { - return result != null; + return resultComplete; } } @@ -126,7 +134,7 @@ public class HighLevelCallback { */ public R getResult(long waitTime) throws InterruptedException { synchronized (syncObject) { - if (result == null) { + while (!resultComplete) { syncObject.wait(waitTime); } return result; @@ -134,16 +142,26 @@ public class HighLevelCallback { } /** - * Sets the result of the operation. Calling this method will result in all - * listeners being notified. + * Returns the result even if it is not yet complete. * - * @see #fireGotResult() - * @param result - * The result of the operation + * @return The result of the operation */ - void setResult(R result) { + R getIntermediaryResult() { synchronized (syncObject) { - this.result = result; + return result; + } + } + + /** + * Marks the result as complete and notify the listeners. If the result was + * already complete, nothing will be done. + */ + void setDone() { + synchronized (syncObject) { + if (resultComplete) { + return; + } + resultComplete = true; syncObject.notifyAll(); } fireGotResult();