This commit is contained in:
Greg Wilkins 2013-05-14 11:33:33 +10:00
parent 0116f45ff0
commit 19d9febfbc
1 changed files with 35 additions and 0 deletions

View File

@ -20,6 +20,26 @@ package org.eclipse.jetty.util;
import java.util.concurrent.atomic.AtomicBoolean;
/* ------------------------------------------------------------ */
/** Iterating Callback.
* <p>This specialised callback is used when breaking up an
* asynchronous task into smaller asynchronous tasks. A typical pattern
* is that a successful callback is used to schedule the next sub task, but
* if that task completes quickly and uses the calling thread to callback
* the success notification, this can result in a growing stack depth.
* </p>
* <p>To avoid this issue, this callback uses an Atomicboolean to note
* if the success callback has been called during the processing of a
* sub task, and if so then the processing iterates rather than recurses.
* </p>
* <p>This callback is passed to the asynchronous handling of each sub
* task and a call the {@link #succeeded()} on this call back represents
* completion of the subtask. Only once all the subtasks are completed is
* the {@link Callback#succeeded()} method called on the {@link Callback} instance
* passed the the {@link #IteratingCallback(Callback)} constructor.</p>
*
*/
public abstract class IteratingCallback implements Callback
{
final AtomicBoolean _iterating = new AtomicBoolean();
@ -31,8 +51,23 @@ public abstract class IteratingCallback implements Callback
_callback=callback;
}
/* ------------------------------------------------------------ */
/**
* Process a subtask.
* <p>Called by {@link #iterate()} to process a sub task of the overall task
* <p>
* @return True if the total task is complete. If false is returned
* then this Callback must be scheduled to receive either a call to
* {@link #succeeded()} or {@link #failed(Throwable)}.
* @throws Exception
*/
abstract protected boolean process() throws Exception;
/* ------------------------------------------------------------ */
/** This method is called initially to start processing and
* is then called by subsequent sub task success to continue
* processing.
*/
public void iterate()
{
try