You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ko...@apache.org on 2006/02/06 16:45:57 UTC

svn commit: r375299 - /jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java

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:stephan@apache.org">Stephan Michels</a>
  * @author <a href="mailto:tcurdt@apache.org">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 {@link #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 {@link #continueWith} or {@link #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 {@link 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 {@link #continueWith} or {@link #startWith} methods.
+     * When called, the execution jumps to where it was resumed
+     * (if the execution has never resumed before, from the beginning
+     * of {@link 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 {@link Continuation#startWith(Runnable)} method and
+     * {@link 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 {@link #again()} method,
+     * but instead of re-executing, this method first suspends the execution.
+     *
+     * <p>
+     * Therefore,
+     * the calling {@link Continuation#startWith(Runnable)} method and
+     * {@link 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: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org