Author: kohsuke
Date: Mon Feb 6 07:45:56 2006
New Revision: 375299
URL: http://svn.apache.org/viewcvs?rev=375299&view=rev
Log:
bug fix in the again() method implementationn.
Modified:
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
Modified:
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
URL:
http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java?rev=375299&r1=375298&r2=375299&view=diff
==============================================================================
---
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
(original)
+++
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
Mon Feb 6 07:45:56 2006
@@ -17,7 +17,6 @@
import java.io.Serializable;
import org.apache.commons.javaflow.bytecode.StackRecorder;
-import org.apache.commons.javaflow.bytecode.ContinuationDeath;
import org.apache.commons.javaflow.utils.ReflectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -38,7 +37,7 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a>
- * @version CVS $Id$
+ * @version CVS $Revision$
*/
public final class Continuation implements Serializable {
@@ -109,9 +108,9 @@
*
* This method blocks until the continuation suspends or completes.
*
- * @param target
+ * @param pTarget
* The object whose <tt>run</tt> method will be executed.
- * @param context
+ * @param pContext
* This value can be obtained from [EMAIL PROTECTED] #getContext()}
until this method returns.
* Can be null.
* @return
@@ -127,7 +126,7 @@
log.debug("starting new flow from " +
ReflectionUtils.getClassName(pTarget) + "/" +
ReflectionUtils.getClassLoaderName(pTarget));
- return execute(new StackRecorder(pTarget), pContext);
+ return continueWith(new Continuation(new StackRecorder(pTarget)),
pContext);
}
/**
@@ -166,15 +165,24 @@
log.debug("continueing with continuation " +
ReflectionUtils.getClassName(pOldContinuation) + "/" +
ReflectionUtils.getClassLoaderName(pOldContinuation));
- return execute(new
StackRecorder(pOldContinuation.stackRecorder),pContext);
- }
-
- private static Continuation execute( StackRecorder pStackRecorder, final
Object pContext) {
- pStackRecorder = pStackRecorder.execute(pContext);
- if(pStackRecorder == null) {
- return null;
- } else {
- return new Continuation(pStackRecorder);
+ while(true) {
+ try {
+ StackRecorder pStackRecorder =
+ new
StackRecorder(pOldContinuation.stackRecorder).execute(pContext);
+ if(pStackRecorder == null) {
+ return null;
+ } else {
+ return new Continuation(pStackRecorder);
+ }
+ } catch (ContinuationDeath e) {
+ if(e.mode.equals(ContinuationDeath.MODE_AGAIN))
+ continue; // re-execute immediately
+ if(e.mode.equals(ContinuationDeath.MODE_EXIT))
+ return null; // no more thing to continue
+ if(e.mode.equals(ContinuationDeath.MODE_CANCEL))
+ return pOldContinuation;
+ throw new IllegalStateException("Illegal mode "+e.mode);
+ }
}
}
@@ -198,15 +206,84 @@
}
/**
- * Exits the running continuation.
+ * Completes the execution of the running continuation.
*
* <p>
* This method can be only called inside [EMAIL PROTECTED] #continueWith}
or [EMAIL PROTECTED] #startWith} methods.
* When called, the thread returns from the above methods with null,
* indicating that there's nothing more to continue.
+ *
+ * <p>
+ * This method is similiar to how [EMAIL PROTECTED] System#exit(int)}
works for JVM.
*/
public static void exit() {
- throw new ContinuationDeath();
+ throw new ContinuationDeath(ContinuationDeath.MODE_EXIT);
+ }
+
+ /**
+ * Jumps to where the execution was resumed.
+ *
+ * <p>
+ * This method can be only called inside [EMAIL PROTECTED] #continueWith}
or [EMAIL PROTECTED] #startWith} methods.
+ * When called, the execution jumps to where it was resumed
+ * (if the execution has never resumed before, from the beginning
+ * of [EMAIL PROTECTED] Runnable#run()}.)
+ *
+ * <p>
+ * Consider the following example:
+ *
+ * <pre>
+ * Continuation.suspend();
+ * System.out.println("resumed");
+ *
+ * r = new Random().nextInt(5);
+ * if(r!=0) {
+ * System.out.println("do it again");
+ * Continuation.again();
+ * }
+ *
+ * System.out.println("done");
+ * </pre>
+ *
+ * <p>
+ * This program produces an output like this (the exact number of
+ * 'do it again' depends on each execution, as it's random.)
+ *
+ * <pre>
+ * resumed
+ * do it again
+ * resumed
+ * do it again
+ * resumed
+ * do it again
+ * resumed
+ * done
+ * </pre>
+ *
+ * <p>
+ * The calling [EMAIL PROTECTED] Continuation#startWith(Runnable)} method
and
+ * [EMAIL PROTECTED] Continuation#continueWith(Continuation)} method does
not
+ * return when a program running inside uses this method.
+ */
+ public static void again() {
+ throw new ContinuationDeath(ContinuationDeath.MODE_AGAIN);
+ }
+
+ /**
+ * Jumps to where the execution was resumed, and suspend execution.
+ *
+ * <p>
+ * This method almost works like the [EMAIL PROTECTED] #again()} method,
+ * but instead of re-executing, this method first suspends the execution.
+ *
+ * <p>
+ * Therefore,
+ * the calling [EMAIL PROTECTED] Continuation#startWith(Runnable)} method
and
+ * [EMAIL PROTECTED] Continuation#continueWith(Continuation)} method
+ * return when a program running inside uses this method.
+ */
+ public static void cancel() {
+ throw new ContinuationDeath(ContinuationDeath.MODE_CANCEL);
}
public String toString() {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]