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]

Reply via email to