# This patch file was generated by NetBeans IDE # Following Index: paths are relative to: C:\Projects\grizzly-ref\trunk\modules\grizzly\src\main\java\com\sun\grizzly # This patch can be applied using context Tools: Patch action on respective folder. # It uses platform neutral UTF-8 encoding and \n newlines. # Above lines and this line are ignored by the patching process. Index: Context.java --- Context.java Base (BASE) +++ Context.java Locally Modified (Based On LOCAL) @@ -49,12 +49,14 @@ 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; import java.nio.channels.SelectionKey; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; /** @@ -186,7 +188,13 @@ */ private boolean isSuspended = false; + /** + * Reference Counter indicating How many Threads share this Context. + * Starts at one allready counting {@link WorkerThread}. + */ + private AtomicInteger refCounter=new AtomicInteger(1); + /** * Constructor */ @@ -365,6 +373,7 @@ attributes.clear(); } isSuspended = false; + refCounter.set(1); } @@ -799,6 +808,7 @@ public void suspend(){ if (isSuspended) return; isSuspended = true; + incrementRefCount(); setKeyRegistrationState(keyRegistrationState.NONE); } @@ -815,15 +825,16 @@ /** - * Resume a {@link #suspend}ed {@link Context}. Invoking this method will - * automatically clean the state of this Context and mark it as a candidate - * for being re-used by another Thread and connection. + * Resume a {@link #suspend}ed {@link Context}. + * Resume will not call {@link Context#recycle}. So + * after the caller is finished using Context caller must + * call {@link Controller#returnContext(com.sun.grizzly.Context)} + * to mark it as a candidate for being re-used by another Thread and connection. * * Important. When resumed, all operations done on this * object are not thread-safe and there is probability that another * thread is already using this object. Never use this object once resumed. * - * * When invoked this method will automatically set the * {@link Context#setKeyRegistrationState} to {@link KeyRegistrationState} * to KeyRegistrationState.REGISTER and automatically re-enable read and @@ -835,8 +846,6 @@ if (!isSuspended) return; isSuspended = false; selectorHandler.register(key, SelectionKey.OP_READ); - recycle(); - getController().returnContext(this); } @@ -859,8 +868,30 @@ if (!isSuspended) return; isSuspended = false; selectorHandler.getSelectionKeyHandler().cancel(key); - recycle(); getController().returnContext(this); } + /** + * Called by outer Threads that are not instances of {@link WorkerThread} to + * indicate that this {@link Context} should not be + * {@link #recycle()} or offered back to its Pool. + * + * When a outer Thread is done with {@link Context} it must call + * {@link Controller#returnContext(com.sun.grizzly.Context) to + * ensure that {@link Context} will be propably recycled. + * + * @return Current Thread reference count + */ + public void incrementRefCount(){ + refCounter.incrementAndGet(); + } + /** + * Decrements the reference count of this Context. + * See {@link Controller#returnContext(com.sun.grizzly.Context)} + * @return return decremented reference count + */ + public int decrementRefCount(){ + return refCounter.decrementAndGet(); } + +}