users@grizzly.java.net

Re: WG: Re: WG: Re: Asynchronous Request Processing with TCPIP

From: John ROM <snake-john_at_gmx.de>
Date: Mon, 07 Jul 2008 10:28:25 +0200

Hi Jeanfrancois,

I tried some changes which worked for me.
The grizzly worker Thread must call Context.blockRecycle(true);
before ist gives the new Thread the context.

I also put synchronized on resume() and isSuspended() because I saw a race condition with ContextTask.recycle()

I show you the code just as an example what works for me:

Index: Context.java
--- Context.java Base (BASE)
+++ Context.java Locally Modified (Based On LOCAL)
@@ -49,6 +49,8 @@
 import com.sun.grizzly.util.AttributeHolder;
 import com.sun.grizzly.util.Copyable;
 import com.sun.grizzly.util.SelectionKeyAttachment;
+import com.sun.grizzly.util.WorkerThread;
+
 import java.io.IOException;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
@@ -186,7 +188,13 @@
      */
     private boolean isSuspended = false;
     
+ /**
+ * Can this Context be recycled
+ */
+ private boolean blockRecycle;
     
+
+
     /**
      * Constructor
      */
@@ -807,11 +815,11 @@
     
     /**
      * Return <tt>true</tt> if this Context has been suspended by
- * invoking {_at_link suspend}. When suspended, invoking {_at_link Context#recycle}
+ * invoking {_at_link #suspend}. When suspended, invoking {_at_link Context#recycle}
      * will throw an {_at_link IllegalStateException}
      * @return <tt>true</tt> if this Context has been suspended
      */
- public boolean isSuspended(){
+ public synchronized boolean isSuspended(){
         return isSuspended;
     }
     
@@ -828,10 +836,11 @@
      *
      * If the Context hasn't been suspended, calling that method has no effet.
      */
- public void resume(){
+ public synchronized void resume(){
         if (!isSuspended) return;
         isSuspended = false;
         selectorHandler.register(key, SelectionKey.OP_READ);
+ if(blockRecycle) return;
         recycle();
         getController().returnContext(this);
     }
@@ -847,12 +856,25 @@
      *
      * If the Context hasn't been suspended, calling that method has no effet.
      */
- public void cancel(){
+ public synchronized void cancel(){
         if (!isSuspended) return;
         isSuspended = false;
         selectorHandler.getSelectionKeyHandler().cancel(key);
+ if(blockRecycle) return;
         recycle();
         getController().returnContext(this);
     }
     
+ /**
+ * A Thread that for example calls {_at_link #suspend()} might not want that a call to
+ * {_at_link #resume()} recycles this {_at_link com.sun.grizzly.Context}. Therefore
+ * a caller can block the recyling and do it later itself
+ *
+ * @param block
+ */
+ public void blockRecycle(boolean block) {
+ this.blockRecycle=block;
 }
+
+
+}


Index: ContextTask.java
--- ContextTask.java Base (BASE)
+++ ContextTask.java Locally Modified (Based On LOCAL)
@@ -59,6 +59,7 @@
     }
     
     public void recycle() {
+ context.blockRecycle(false);
         // Do not recycle when suspended.
         if (context.isSuspended()){
             return;


Many Greetings
John
-- 
Psssst! Schon das coole Video vom GMX MultiMessenger gesehen?
Der Eine für Alle: http://www.gmx.net/de/go/messenger03