[javaflow] More small changes to Continuation

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[javaflow] More small changes to Continuation

Kohsuke Kawaguchi

I'm setting up IDE with Cocoon, but meanwhile, more small changes.

1. replaced HashMap<Thread,Continuation> by ThreadLocal, as it does the
job better (w/o synchronization). No point in marking static fields as
transient.

2. I believe the current code doesn't run correctly if a thread running
a continuation tries to run another continuation inside it. I fixed that.

3. added serialVersionUID. According to Java serialization experts at my
work, any serializable class should have it. I assumed we aren't
worrying about the backward compatibility right now, so I just set 1.

4. javadoc improvement on the continueWith method.

--
Kohsuke Kawaguchi

Index: src/java/org/apache/commons/javaflow/Continuation.java
===================================================================
--- src/java/org/apache/commons/javaflow/Continuation.java (revision 226309)
+++ src/java/org/apache/commons/javaflow/Continuation.java (working copy)
@@ -17,8 +17,6 @@
 
 import java.io.Serializable;
 import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
 
 import org.apache.commons.javaflow.bytecode.Stack;
 import org.apache.commons.logging.Log;
@@ -36,7 +34,7 @@
 
     private final static Log log = LogFactory.getLog(Continuation.class);
     
-    private final static transient Map continuationsMap = new HashMap();
+    private final static ThreadLocal continuationsMap = new ThreadLocal();
     private transient ContinuationContext context;
 
     private transient boolean restoring = false;
@@ -94,19 +92,25 @@
     }
     
     /**
-     * Creates a new continuation to capture the
-     * next state. Resume where the old one was
-     * suspended.
-     *
-     * @param parent parent continuation or null
-     * @param context context of the continuation
-     * @return new child continuation
+     * Resumes the execution of the specified continuation from where it's left off.
+     *
+     * This method blocks until the continuation suspends or completes.
+     *
+     * @param resumed
+     *      The resumed continuation to be executed. Must not be null.
+     * @param context
+     *      This value can be obtained from {@link #getContext()} until this method returns.
+     *      <!-- Can be null. -->
+     * @return
+     *      If the execution completes and there's nothing more to continue, return null.
+     *      Otherwise, the execution has been {@link #suspend() suspended}, in which case
+     *      a new non-null continuation is returned.
      */
-    public static Continuation continueWith(final Continuation oldContinuation, final ContinuationContext context) {
+    public static Continuation continueWith(final Continuation resumed, final ContinuationContext context) {
 
-        log.debug("continueing with continuation " + oldContinuation);
+        log.debug("continueing with continuation " + resumed);
 
-        final Continuation newContinuation = new Continuation(oldContinuation);
+        final Continuation newContinuation = new Continuation(resumed);
 
         newContinuation.restoring = true;
         
@@ -115,9 +119,9 @@
 
     private static Continuation execute(final Continuation continuation, final ContinuationContext context) {
         boolean completed = false;
+
+        final Continuation runningContinuation = continuation.registerThread();
         try {
-            continuation.registerThread();
-            
             // REVISIT: use instance from root continuation
             
             if (continuation.method == null) {
@@ -156,7 +160,7 @@
 
             continuation.context = null;
             
-            continuation.deregisterThread();
+            continuation.deregisterThread(runningContinuation);
         }
 
         if(completed) {
@@ -206,31 +210,29 @@
     /**
      * Bind the continuation to running thread.
      */
-    private void registerThread() {
-        synchronized (continuationsMap) {
-            continuationsMap.put(Thread.currentThread(), this);
-        }
+    private Continuation registerThread() {
+        Continuation old = currentContinuation();
+        continuationsMap.set(this);
+        return old;
     }
 
     /**
      * Unbind the continuation to running thread.
      */
-    private void deregisterThread() {
-        synchronized (continuationsMap) {
-            continuationsMap.remove(Thread.currentThread());
-        }
+    private void deregisterThread(Continuation old) {
+        continuationsMap.set(old);
     }
 
     /**
      * Return the continuation, which is associated to the current thread.
      */
     public static Continuation currentContinuation() {
-        synchronized (continuationsMap) {
-            return (Continuation) continuationsMap.get(Thread.currentThread());
-        }
+        return (Continuation)continuationsMap.get();
     }
     
     public String toString() {
         return "Continuation@" + hashCode() + " in " + getClass().getClassLoader();
     }
+
+    private static final long serialVersionUID = 1L;
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]