Hi,
>> some other place, where connection info could be stored.
>> IMHO SelectionKey attachment could be good place for it.
>
> Performance wise, it can cause trouble so we need to be careful here:
>
> http://weblogs.java.net/blog/jfarcand/archive/2006/06/tricks_and_tips.html
>
>
> Unifying/improving our solution is great, we just have to make sure
> our users knows that can have potential issues.
Agree. But that change we will not try to inspire people to use
SelectionKey attachments where it's possible. But if they really need to
- we will have better order there, which will reduce possibility of
memory leaks and other possible problems.
>> Think, in 2.x branch we will be able to have clear and complete
>> SelectionKey attachment implementation, which will include
>> CallbackHandlers etc.
>
>
> Like discussed at the meeting, I would propose we implement a complete
> solution (event if we break compatibility). Let's works on the proposal!
Ok, here it is.
Thanks.
WBR,
Alexey.
>
> A+
>
> -- jeanfrancois
>
>
>>
>> Thanks.
>>
>> WBR,
>> Alexey.
>>
>> # This patch file was generated by NetBeans IDE
>> # Following Index: paths are relative to:
>> C:\Projects\Grizzly\trunk\modules\grizzly\src
>> # 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: main/java/com/sun/grizzly/async/AsyncQueueReaderContextTask.java
>> --- main/java/com/sun/grizzly/async/AsyncQueueReaderContextTask.java
>> Base (BASE)
>> +++ main/java/com/sun/grizzly/async/AsyncQueueReaderContextTask.java
>> Locally Modified (Based On LOCAL)
>> @@ -23,7 +23,7 @@
>>
>> package com.sun.grizzly.async;
>>
>> -import com.sun.grizzly.ContextTask;
>> +import com.sun.grizzly.SelectionKeyContextTask;
>> import java.nio.channels.SelectionKey;
>>
>>
>> @@ -35,11 +35,11 @@
>> * * @author Alexey Stashok
>> */
>> -public class AsyncQueueReaderContextTask extends ContextTask {
>> +public class AsyncQueueReaderContextTask extends
>> SelectionKeyContextTask {
>> private static final TaskPool<AsyncQueueReaderContextTask>
>> taskPool =
>> new TaskPool<AsyncQueueReaderContextTask>() {
>> @Override
>> - public AsyncQueueReaderContextTask newTask() {
>> + public AsyncQueueReaderContextTask newInstance() {
>> return new AsyncQueueReaderContextTask();
>> }
>> };
>> @@ -55,7 +55,7 @@
>> taskPool.offer(contextTask);
>> }
>> - public Object call() throws Exception {
>> + public Object doCall() throws Exception {
>> try {
>> SelectionKey selectionKey = context.getSelectionKey();
>> if (selectionKey == null) {
>> Index: main/java/com/sun/grizzly/async/AsyncQueueWriterContextTask.java
>> --- main/java/com/sun/grizzly/async/AsyncQueueWriterContextTask.java
>> Base (BASE)
>> +++ main/java/com/sun/grizzly/async/AsyncQueueWriterContextTask.java
>> Locally Modified (Based On LOCAL)
>> @@ -23,7 +23,7 @@
>>
>> package com.sun.grizzly.async;
>>
>> -import com.sun.grizzly.ContextTask;
>> +import com.sun.grizzly.SelectionKeyContextTask;
>> import java.nio.channels.SelectionKey;
>>
>>
>> @@ -35,11 +35,11 @@
>> * * @author Alexey Stashok
>> */
>> -public class AsyncQueueWriterContextTask extends ContextTask {
>> +public class AsyncQueueWriterContextTask extends
>> SelectionKeyContextTask {
>> private static final TaskPool<AsyncQueueWriterContextTask>
>> taskPool =
>> new TaskPool<AsyncQueueWriterContextTask>() {
>> @Override
>> - public AsyncQueueWriterContextTask newTask() {
>> + public AsyncQueueWriterContextTask newInstance() {
>> return new AsyncQueueWriterContextTask();
>> }
>> };
>> @@ -55,7 +55,7 @@
>> taskPool.offer(contextTask);
>> }
>> - public Object call() throws Exception {
>> + protected Object doCall() throws Exception {
>> try {
>> SelectionKey selectionKey = context.getSelectionKey();
>> if (selectionKey == null) {
>> Index: main/java/com/sun/grizzly/CallbackHandlerContextTask.java
>> --- main/java/com/sun/grizzly/CallbackHandlerContextTask.java Base
>> (BASE)
>> +++ main/java/com/sun/grizzly/CallbackHandlerContextTask.java Locally
>> Modified (Based On LOCAL)
>> @@ -33,11 +33,11 @@
>> * * @author Alexey Stashok
>> */
>> -public class CallbackHandlerContextTask extends ContextTask {
>> +public class CallbackHandlerContextTask extends
>> SelectionKeyContextTask {
>> private static final TaskPool<CallbackHandlerContextTask>
>> taskPool = new TaskPool<CallbackHandlerContextTask>() {
>> @Override
>> - public CallbackHandlerContextTask newTask() {
>> + public CallbackHandlerContextTask newInstance() {
>> return new CallbackHandlerContextTask();
>> }
>> };
>> @@ -53,7 +53,7 @@
>> taskPool.offer(contextTask);
>> }
>> - public Object call() throws Exception {
>> + protected Object doCall() throws Exception {
>> IOEvent ioEvent = context.getIOEvent();
>> OpType currentOpType = context.getCurrentOpType();
>> @@ -93,6 +93,4 @@
>> callBackHandler = null;
>> super.recycle();
>> }
>> - - }
>> Index: main/java/com/sun/grizzly/Context.java
>> --- main/java/com/sun/grizzly/Context.java Base (BASE)
>> +++ main/java/com/sun/grizzly/Context.java Locally Modified (Based On
>> LOCAL)
>> @@ -32,6 +32,7 @@
>> import com.sun.grizzly.async.AsyncReadCondition;
>> import com.sun.grizzly.async.AsyncWriteCallbackHandler;
>> import com.sun.grizzly.util.AttributeHolder;
>> +import com.sun.grizzly.util.SelectionKeyAttachment;
>> import java.io.IOException;
>> import java.net.SocketAddress;
>> import java.nio.ByteBuffer;
>> @@ -373,7 +374,7 @@
>> // If a IOEvent has been defined, invoke it first and
>> // let its associated CallbackHandler decide if the
>> ProtocolChain
>> // be invoked or not.
>> - Object attachment = key.attachment();
>> + Object attachment = SelectionKeyAttachment.getAttachment(key);
>> if (ioEvent != null && (attachment instanceof
>> CallbackHandler)) {
>> CallbackHandlerContextTask task =
>> CallbackHandlerContextTask.poll();
>> task.setCallBackHandler((CallbackHandler) attachment);
>> Index: main/java/com/sun/grizzly/ContextTask.java
>> --- main/java/com/sun/grizzly/ContextTask.java Base (BASE)
>> +++ main/java/com/sun/grizzly/ContextTask.java Locally Modified
>> (Based On LOCAL)
>> @@ -23,6 +23,7 @@
>>
>> package com.sun.grizzly;
>>
>> +import com.sun.grizzly.util.ConcurrentLinkedQueuePool;
>> import java.util.concurrent.Callable;
>> import java.util.concurrent.ConcurrentLinkedQueue;
>>
>> @@ -47,24 +48,13 @@
>> context = null;
>> }
>> - protected abstract static class TaskPool<E extends
>> ContextTask> {
>> - private ConcurrentLinkedQueue<E> pool = - new
>> ConcurrentLinkedQueue<E>();
>> + protected abstract static class TaskPool<E extends ContextTask>
>> + extends ConcurrentLinkedQueuePool<E> {
>> - public abstract E newTask();
>> - - public E poll() {
>> - E task = pool.poll();
>> - if (task == null) {
>> - task = newTask();
>> - }
>> - - return task;
>> - }
>> - + @Override
>> public void offer(E task) {
>> task.recycle();
>> - pool.offer(task);
>> + super.offer(task);
>> }
>> }
>> }
>> Index: main/java/com/sun/grizzly/Controller.java
>> --- main/java/com/sun/grizzly/Controller.java Base (BASE)
>> +++ main/java/com/sun/grizzly/Controller.java Locally Modified (Based
>> On LOCAL)
>> @@ -25,6 +25,7 @@
>>
>> import com.sun.grizzly.util.AttributeHolder;
>> import com.sun.grizzly.util.Cloner;
>> +import com.sun.grizzly.util.ConcurrentLinkedQueuePool;
>> import com.sun.grizzly.util.Copyable;
>> import com.sun.grizzly.util.State;
>> import com.sun.grizzly.util.StateHolder;
>> @@ -135,7 +136,7 @@
>> /**
>> * A cached list of Context. Context are by default stateless.
>> */
>> - private ConcurrentLinkedQueue<Context> contexts;
>> + private ConcurrentLinkedQueuePool<Context> contexts;
>> /**
>> @@ -239,7 +240,13 @@
>> * Controller constructor
>> */
>> public Controller() {
>> - contexts = new ConcurrentLinkedQueue<Context>();
>> + contexts = new ConcurrentLinkedQueuePool<Context>() {
>> + @Override
>> + public Context newInstance() {
>> + return new Context();
>> + }
>> + };
>> + stateHolder = new StateHolder<State>(true);
>> }
>> @@ -262,10 +269,8 @@
>> ProtocolChainInstanceHandler pciHandler = null;
>> ProtocolChain protocolChain = null;
>> Context serverCtx = contexts.poll();
>> - if (serverCtx == null){
>> - serverCtx = new Context();
>> serverCtx.setController(this);
>> - }
>> + serverCtx.setSelectorHandler(selectorHandler);
>> try {
>> @@ -474,9 +479,6 @@
>> */ public Context pollContext(SelectionKey key){
>> Context ctx = contexts.poll();
>> - if (ctx == null){
>> - ctx = new Context();
>> - }
>> ctx.setController(this);
>> ctx.setSelectionKey(key);
>> return ctx;
>> Index: main/java/com/sun/grizzly/DefaultSelectionKeyHandler.java
>> --- main/java/com/sun/grizzly/DefaultSelectionKeyHandler.java Base
>> (BASE)
>> +++ main/java/com/sun/grizzly/DefaultSelectionKeyHandler.java Locally
>> Modified (Based On LOCAL)
>> @@ -23,8 +23,9 @@
>>
>> package com.sun.grizzly;
>>
>> +import com.sun.grizzly.util.SelectionKeyAttachment;
>> +import com.sun.grizzly.util.SelectionKeyActionAttachment;
>> import com.sun.grizzly.util.Copyable;
>> -import com.sun.grizzly.util.ThreadAttachment;
>> import java.io.IOException;
>> import java.net.Socket;
>> import java.nio.channels.ClosedChannelException;
>> @@ -34,11 +35,7 @@
>> import java.util.Iterator;
>> import java.util.logging.Level;
>> import java.util.logging.Logger;
>> -import javax.net.ssl.SSLEngine;
>> -import javax.net.ssl.SSLSession;
>>
>> -import static com.sun.grizzly.filter.SSLReadFilter.EXPIRE_TIME;
>> -import com.sun.grizzly.util.WorkerThread;
>> import java.nio.channels.Selector;
>>
>> /**
>> @@ -103,6 +100,12 @@
>> * {_at_inheritDoc}
>> */
>> public void process(SelectionKey key) {
>> + Object attachment = key.attachment();
>> + + if (attachment instanceof
>> SelectionKeyActionAttachment) {
>> + ((SelectionKeyActionAttachment) attachment).process(key);
>> + }
>> +
>> removeExpirationStamp(key);
>> }
>> @@ -238,6 +241,11 @@
>> closeChannel(key.channel());
>> }
>> + Object attachment = key.attachment();
>> + if (attachment instanceof SelectionKeyAttachment) {
>> + ((SelectionKeyAttachment) attachment).release();
>> + }
>> + key.attach(null);
>> key.cancel();
>> key = null;
>> @@ -309,13 +317,8 @@
>> if (attachment != null) {
>> if (attachment instanceof Long) {
>> key.attach(null);
>> - } else if (attachment instanceof ThreadAttachment) {
>> - ((WorkerThread) Thread.currentThread()).attach(
>> - (ThreadAttachment) attachment);
>> - key.attach(null);
>> - } else if (attachment instanceof SSLEngine) {
>> - SSLEngine sslEngine = (SSLEngine) attachment;
>> - sslEngine.getSession().removeValue(EXPIRE_TIME);
>> + } else if (attachment instanceof SelectionKeyAttachment) {
>> + ((SelectionKeyAttachment) attachment).setTimeout(null);
>> }
>> }
>> }
>> @@ -331,11 +334,8 @@
>> Object attachment = key.attachment();
>> if (attachment == null) {
>> key.attach(currentTime);
>> - } else if (attachment instanceof ThreadAttachment) {
>> - ((ThreadAttachment) attachment).setTimeout(currentTime);
>> - } else if (attachment instanceof SSLEngine) {
>> - SSLEngine sslEngine = (SSLEngine) attachment;
>> -
>> sslEngine.getSession().putValue(EXPIRE_TIME,currentTime); +
>> } else if (attachment instanceof SelectionKeyAttachment) {
>> + ((SelectionKeyAttachment)
>> attachment).setTimeout(currentTime);
>> } }
>> @@ -356,17 +356,9 @@
>> // can't predict the type of the attached
>> object. if
>> (attachment instanceof Long) {
>> return (Long) attachment;
>> - } else if (attachment instanceof SSLEngine) {
>> - SSLSession sslSession = ((SSLEngine)
>> attachment).getSession();
>> - if (sslSession != null &&
>> - sslSession.getValue(EXPIRE_TIME) != null) {
>> - return (Long) sslSession.getValue(EXPIRE_TIME);
>> + } else if (attachment instanceof
>> SelectionKeyAttachment) {
>> + return ((SelectionKeyAttachment)
>> attachment).getTimeout();
>> }
>> -
>> - return null;
>> - } else if (attachment instanceof ThreadAttachment) {
>> - return ((ThreadAttachment)
>> attachment).getTimeout();
>> - }
>> } catch (ClassCastException ex) {
>> if (logger.isLoggable(Level.FINEST)) {
>> logger.log(Level.FINEST, Index:
>> main/java/com/sun/grizzly/filter/SSLReadFilter.java
>> --- main/java/com/sun/grizzly/filter/SSLReadFilter.java Base (BASE)
>> +++ main/java/com/sun/grizzly/filter/SSLReadFilter.java Locally
>> Modified (Based On LOCAL)
>> @@ -27,7 +27,9 @@
>> import com.sun.grizzly.Controller;
>> import com.sun.grizzly.ProtocolFilter;
>> import com.sun.grizzly.SSLConfig;
>> +import com.sun.grizzly.util.SSLSelectionKeyAttachment;
>> import com.sun.grizzly.util.SSLUtils;
>> +import com.sun.grizzly.util.SelectionKeyAttachment;
>> import com.sun.grizzly.util.WorkerThreadImpl;
>> import java.io.EOFException;
>> import java.io.IOException;
>> @@ -49,14 +51,6 @@
>> * @author Jeanfrancois Arcand
>> */
>> public class SSLReadFilter implements ProtocolFilter{
>> - - public final static String HANDSHAKE = "handshake";
>> - public final static String DATA_DECODED = "dataDecoded";
>> - public final static String INPUT_BB_REMAINDER = "inputBBRemainder";
>> - public final static String OUTPUT_BB_REMAINDER =
>> "outputBBRemainder";
>> - - - /**
>> * The <code>SSLContext</code> associated with the SSL
>> implementation
>> * we are running on.
>> @@ -95,12 +89,6 @@
>> /**
>> - * Session keep-alive flag.
>> - */
>> - public final static String EXPIRE_TIME = "expireTime";
>> - - - /**
>> * Has the enabled protocol configured.
>> */
>> private boolean isProtocolConfigured = false;
>> @@ -125,7 +113,6 @@
>> public boolean execute(Context ctx) throws IOException {
>> boolean result = true;
>> int count = 0;
>> - boolean isCopied = false;
>> Throwable exception = null;
>> SelectionKey key = ctx.getSelectionKey();
>> WorkerThreadImpl workerThread; @@ -137,22 +124,16 @@
>>
>> SSLEngine sslEngine = newSSLEngine(key);
>> workerThread.setSSLEngine(sslEngine);
>> - key.attach(sslEngine);
>> + SSLSelectionKeyAttachment.attach(key, sslEngine);
>>
>> - boolean hasHandshake = Boolean.TRUE.equals(
>> - sslEngine.getSession().getValue(HANDSHAKE));
>> -
>> - restoreSecuredBufferRemainders(sslEngine);
>> + boolean hasHandshake = sslEngine.getSession().isValid();
>> try {
>> allocateBuffers();
>> - isCopied = copyByteBufferToInputBB(sslEngine,
>> - workerThread.getByteBuffer(),
>> workerThread.getInputBB());
>> if (hasHandshake) {
>> count = doRead(key);
>> } else if (doHandshake(key, SSLUtils.getReadTimeout())) {
>> hasHandshake = true;
>> - sslEngine.getSession().putValue(HANDSHAKE,
>> Boolean.TRUE);
>> // set "no available data" for
>> secured output buffer
>> ByteBuffer outputBB = workerThread.getOutputBB();
>> @@ -168,12 +149,6 @@
>> log("SSLReadFilter.execute",ex);
>> } finally { if (exception != null ||
>> count == -1){
>> - if (isCopied) {
>> - /* if some data was copied from ByteBuffer,
>> - * but connection got closed - clean inputBB */
>> - workerThread.getInputBB().clear();
>> - }
>> -
>> ctx.setAttribute(Context.THROWABLE,exception);
>> ctx.setKeyRegistrationState(
>> Context.KeyRegistrationState.CANCEL);
>> @@ -199,8 +174,7 @@
>> cancel(ctx.getSelectionKey());
>> } else if (ctx.getKeyRegistrationState()
>> ==
>> Context.KeyRegistrationState.REGISTER){ -
>> SSLEngine sslEngine = (SSLEngine) ctx.getSelectionKey().attachment();
>> - saveSecuredBufferRemainders(sslEngine);
>> + saveSecuredBufferRemainders(ctx.getSelectionKey());
>> ctx.getSelectorHandler().register(ctx.getSelectionKey(),
>> SelectionKey.OP_READ);
>>
>> ctx.setKeyRegistrationState(Context.KeyRegistrationState.NONE);
>> @@ -295,20 +269,20 @@
>> } - private static int doRead(SelectionKey key){
>> + private static int doRead(SelectionKey key) {
>> final WorkerThreadImpl workerThread = -
>> (WorkerThreadImpl)Thread.currentThread();
>> + (WorkerThreadImpl) Thread.currentThread();
>> ByteBuffer byteBuffer = workerThread.getByteBuffer();
>> ByteBuffer outputBB = workerThread.getOutputBB();
>> ByteBuffer inputBB = workerThread.getInputBB();
>> SSLEngine sslEngine = workerThread.getSSLEngine();
>> int count = -1;
>> - try{
>> + try {
>> // Read first bytes to avoid continuing if the client
>> // closed the connection.
>> - count = ((SocketChannel)key.channel()).read(inputBB);
>> - if (count != -1){
>> + count = ((SocketChannel) key.channel()).read(inputBB);
>> + if (count != -1) {
>> // Decrypt the bytes we just read.
>> if (Controller.logger().isLoggable(Level.FINE)) {
>> Controller.logger().log(Level.FINE, @@ -318,21
>> +292,20 @@
>> }
>> byteBuffer =
>> -
>> SSLUtils.unwrapAll(byteBuffer,inputBB,sslEngine);
>> + SSLUtils.unwrapAll(byteBuffer, inputBB,
>> sslEngine);
>> workerThread.setInputBB(inputBB);
>> workerThread.setOutputBB(outputBB);
>> workerThread.setByteBuffer(byteBuffer);
>> }
>> return count;
>> - } catch(IOException ex){
>> + } catch (IOException ex) {
>> log("Exception during SSL read.", ex);
>> return -1;
>> } finally {
>> - if (count == -1){
>> - try{
>> + if (count == -1) {
>> + try {
>> sslEngine.closeInbound();
>> - } catch (SSLException ex){
>> - ;
>> + } catch (SSLException ex) {
>> }
>> }
>> }
>> @@ -399,13 +372,12 @@
>> SSLEngine sslEngine = null;
>> if (key.attachment() == null){
>> sslEngine = newSSLEngine();
>> - } else if (key.attachment() instanceof SSLEngine){
>> - sslEngine = (SSLEngine)key.attachment();
>> + } else if (key.attachment() instanceof
>> SSLSelectionKeyAttachment){
>> + sslEngine = ((SSLSelectionKeyAttachment)
>> SelectionKeyAttachment.getAttachment(key)).getSslEngine();
>> } else {
>> sslEngine = newSSLEngine();
>> }
>> sslEngine.setWantClientAuth(wantClientAuth);
>> - sslEngine.getSession().removeValue(EXPIRE_TIME);
>> sslEngine.setNeedClientAuth(needClientAuth);
>> return sslEngine;
>> }
>> @@ -613,78 +585,28 @@
>> return ciphers;
>> }
>>
>> - /**
>> - * If bytebuffer is not empty it means that previous - *
>> <code>ProtocolFilter</code>s has read some data already. This data
>> - * should be copied to the inputBB.
>> - */
>> - private static boolean copyByteBufferToInputBB(SSLEngine sslEngine,
>> - ByteBuffer byteBuffer, ByteBuffer inputBB) {
>> - if (byteBuffer.position() > 0) {
>> - Boolean isDataDecoded = - (Boolean)
>> sslEngine.getSession().getValue(DATA_DECODED);
>> + private void saveSecuredBufferRemainders(SelectionKey
>> selectionKey) {
>> + SSLSelectionKeyAttachment attachment = +
>> (SSLSelectionKeyAttachment) selectionKey.attachment();
>> - if (!Boolean.TRUE.equals(isDataDecoded)) {
>> - byteBuffer.flip();
>> - inputBB.put(byteBuffer);
>> - byteBuffer.clear();
>> - return true;
>> - } else if (isDataDecoded != null) {
>> - sslEngine.getSession().removeValue(DATA_DECODED);
>> - }
>> - }
>> - - return false;
>> - }
>> - - /**
>> - * Restores (if required) secure buffers, associated with
>> <code>SSLEngine</code>,
>> - * which were saved during previous SSLReadFilter execution.
>> - * It makes possible data, which wasn't processed on previous
>> cycle to be processed now
>> - */
>> - private void restoreSecuredBufferRemainders(SSLEngine sslEngine) {
>> - WorkerThreadImpl workerThread = (WorkerThreadImpl)
>> Thread.currentThread(); -
>> - ByteBuffer inputBBRemainder = (ByteBuffer)
>> sslEngine.getSession().
>> - getValue(INPUT_BB_REMAINDER);
>> - if (inputBBRemainder != null) {
>> - sslEngine.getSession().removeValue(INPUT_BB_REMAINDER);
>> - workerThread.setInputBB(inputBBRemainder);
>> - }
>> - - ByteBuffer outputBBRemainder = (ByteBuffer)
>> sslEngine.getSession().
>> - getValue(OUTPUT_BB_REMAINDER);
>> - if (outputBBRemainder != null) {
>> - sslEngine.getSession().removeValue(OUTPUT_BB_REMAINDER);
>> - workerThread.setOutputBB(outputBBRemainder);
>> - }
>> - }
>> - - /**
>> - * Saves (if required) secure buffers, associated with
>> <code>SSLEngine</code>
>> - * If secured data, associated with <code>SSLEngine</code>, is
>> not completely
>> - * processed now (may be additional data is required) - then it
>> could be processed
>> - * on next SSLReadFilter execution.
>> - */
>> - private void saveSecuredBufferRemainders(SSLEngine sslEngine) {
>> - WorkerThreadImpl workerThread = (WorkerThreadImpl)
>> Thread.currentThread(); -
>> - if (sslEngine == null) {
>> + if (attachment == null) {
>> Controller.logger().log(Level.FINE, -
>> "SSLEngine is NULL, when saving buffers");
>> + "SelectionKey attachment is NULL, when saving
>> buffers");
>> return;
>> }
>> + WorkerThreadImpl workerThread = (WorkerThreadImpl)
>> Thread.currentThread(); +
>> ByteBuffer inputBB = workerThread.getInputBB();
>> if (inputBB != null && inputBB.hasRemaining()) {
>> - sslEngine.getSession().putValue(INPUT_BB_REMAINDER,
>> inputBB);
>> workerThread.setInputBB(null);
>> + attachment.setInputBB(inputBB);
>> }
>>
>> ByteBuffer outputBB = workerThread.getOutputBB();
>> if (outputBB != null && outputBB.hasRemaining()) {
>> - sslEngine.getSession().putValue(OUTPUT_BB_REMAINDER,
>> outputBB);
>> workerThread.setOutputBB(null);
>> + attachment.setOutputBB(outputBB);
>> }
>> }
>> Index: main/java/com/sun/grizzly/ProtocolChainContextTask.java
>> --- main/java/com/sun/grizzly/ProtocolChainContextTask.java Base (BASE)
>> +++ main/java/com/sun/grizzly/ProtocolChainContextTask.java Locally
>> Modified (Based On LOCAL)
>> @@ -24,8 +24,6 @@
>>
>> package com.sun.grizzly;
>>
>> -import java.nio.channels.SelectionKey;
>> -
>> /**
>> * <code>ProtocolChain</code> task, which will be executed by *
>> <code>Context</code>, when Context.execute(<code>ContextTask</code>)
>> @@ -33,11 +31,11 @@
>> * * @author Alexey Stashok
>> */
>> -public class ProtocolChainContextTask extends ContextTask {
>> +public class ProtocolChainContextTask extends SelectionKeyContextTask {
>> private static final TaskPool<ProtocolChainContextTask> taskPool
>> = new TaskPool<ProtocolChainContextTask>() {
>> @Override
>> - public ProtocolChainContextTask newTask() {
>> + public ProtocolChainContextTask newInstance() {
>> return new ProtocolChainContextTask();
>> }
>> };
>> @@ -51,16 +49,10 @@
>> taskPool.offer(contextTask);
>> }
>> - public Object call() throws Exception {
>> - SelectionKey currentKey = context.getSelectionKey();
>> - SelectionKeyHandler selectionKeyHandler = context.
>> - getSelectorHandler().getSelectionKeyHandler();
>> - - selectionKeyHandler.process(currentKey);
>> + protected Object doCall() throws Exception {
>> try {
>> context.getProtocolChain().execute(context);
>> } finally {
>> - selectionKeyHandler.postProcess(currentKey);
>> offer(this);
>> }
>> Index: main/java/com/sun/grizzly/SelectionKeyContextTask.java
>> --- main/java/com/sun/grizzly/SelectionKeyContextTask.java Locally New
>> +++ main/java/com/sun/grizzly/SelectionKeyContextTask.java Locally New
>> @@ -0,0 +1,66 @@
>> +/*
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + * + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the "License"). You
>> + * may not use this file except in compliance with the License. You
>> can obtain
>> + * a copy of the License at
>> https://glassfish.dev.java.net/public/CDDL+GPL.html
>> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for
>> the specific
>> + * language governing permissions and limitations under the License.
>> + * + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at
>> glassfish/bootstrap/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the "Classpath"
>> exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + * + * Contributor(s):
>> + * + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this file
>> under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL Version
>> 2 code
>> + * and therefore, elected the GPL Version 2 license, then the option
>> applies
>> + * only if the new code is made subject to such option by the copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.grizzly;
>> +
>> +import java.nio.channels.SelectionKey;
>> +
>> +/**
>> + * Basic class for all <code>ContextTask</code>s, which are dealing
>> with
>> + * <code>SelectionKey</code>s
>> + * + * @author Alexey Stashok
>> + */
>> +public abstract class SelectionKeyContextTask extends ContextTask {
>> +
>> + public final Object call() throws Exception {
>> + Object result = null;
>> + SelectionKey currentKey = context.getSelectionKey();
>> + SelectionKeyHandler selectionKeyHandler = context.
>> + getSelectorHandler().getSelectionKeyHandler();
>> + + selectionKeyHandler.process(currentKey);
>> + try {
>> + result = doCall();
>> + } finally {
>> + selectionKeyHandler.postProcess(currentKey);
>> + }
>> + + return result;
>> + }
>> + + protected abstract Object doCall() throws Exception;
>> +}
>> Index: main/java/com/sun/grizzly/TCPSelectorHandler.java
>> --- main/java/com/sun/grizzly/TCPSelectorHandler.java Base (BASE)
>> +++ main/java/com/sun/grizzly/TCPSelectorHandler.java Locally
>> Modified (Based On LOCAL)
>> @@ -31,6 +31,7 @@
>> import com.sun.grizzly.async.TCPAsyncQueueReader;
>> import com.sun.grizzly.util.Cloner;
>> import com.sun.grizzly.util.Copyable;
>> +import com.sun.grizzly.util.SelectionKeyAttachment;
>> import com.sun.grizzly.util.SelectionKeyOP;
>> import com.sun.grizzly.util.SelectionKeyOP.ConnectSelectionKeyOP;
>> import com.sun.grizzly.util.State;
>> @@ -610,7 +611,7 @@
>> throws IOException{
>> // disable OP_READ on key before doing anything else
>> key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));
>> - Object attach = key.attachment();
>> + Object attach = SelectionKeyAttachment.getAttachment(key);
>> if
>> (asyncQueueReader.isAsyncQueueReaderEnabledFor(key)) {
>> final Context context = pollContext(ctx, key);
>> @@ -646,7 +647,8 @@
>> context.setCurrentOpType(Context.OpType.OP_WRITE);
>> invokeAsyncQueueWriter(context);
>> return false;
>> - } else if ((attach = key.attachment()) instanceof
>> CallbackHandler){
>> + } else if ((attach =
>> SelectionKeyAttachment.getAttachment(key)) +
>> instanceof CallbackHandler){
>> final Context context = pollContext(ctx, key);
>> context.setCurrentOpType(Context.OpType.OP_WRITE);
>> invokeCallbackHandler((CallbackHandler) attach, context);
>> @@ -671,7 +673,7 @@
>> key.interestOps(key.interestOps() & (~SelectionKey.OP_WRITE));
>> key.interestOps(key.interestOps() & (~SelectionKey.OP_READ));
>> - Object attach = key.attachment();
>> + Object attach = SelectionKeyAttachment.getAttachment(key);
>> if (attach instanceof CallbackHandler){
>> final Context context = pollContext(ctx, key);
>> context.setCurrentOpType(Context.OpType.OP_CONNECT);
>> Index: main/java/com/sun/grizzly/util/ConcurrentLinkedQueuePool.java
>> --- main/java/com/sun/grizzly/util/ConcurrentLinkedQueuePool.java
>> Locally New
>> +++ main/java/com/sun/grizzly/util/ConcurrentLinkedQueuePool.java
>> Locally New
>> @@ -0,0 +1,60 @@
>> +/*
>> + * The contents of this file are subject to the terms
>> + * of the Common Development and Distribution License
>> + * (the License). You may not use this file except in
>> + * compliance with the License.
>> + *
>> + * You can obtain a copy of the license at
>> + * https://glassfish.dev.java.net/public/CDDLv1.0.html or
>> + * glassfish/bootstrap/legal/CDDLv1.0.txt.
>> + * See the License for the specific language governing
>> + * permissions and limitations under the License.
>> + *
>> + * When distributing Covered Code, include this CDDL
>> + * Header Notice in each file and include the License file
>> + * at glassfish/bootstrap/legal/CDDLv1.0.txt.
>> + * If applicable, add the following below the CDDL Header,
>> + * with the fields enclosed by brackets [] replaced by
>> + * you own identifying information:
>> + * "Portions Copyrighted [year] [name of copyright owner]"
>> + *
>> + * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
>> + */
>> +
>> +package com.sun.grizzly.util;
>> +
>> +import java.util.concurrent.ConcurrentLinkedQueue;
>> +
>> +/**
>> + * <code>ObjectPool</code> implementation based on
>> <code>ConcurrentLinkedQueue</code>
>> + * + * @author Alexey Stashok
>> + */
>> +public abstract class ConcurrentLinkedQueuePool<E> implements
>> ObjectPool<E> {
>> + private volatile ConcurrentLinkedQueue<E> pool;
>> +
>> + public abstract E newInstance();
>> +
>> + public E poll() {
>> + if (pool == null) {
>> + synchronized(this) {
>> + if (pool == null) {
>> + pool = new ConcurrentLinkedQueue<E>();
>> + }
>> + }
>> + }
>> + + E object = pool.poll();
>> + if (object == null) {
>> + object = newInstance();
>> + }
>> +
>> + return object;
>> + }
>> +
>> + public void offer(E object) {
>> + if (pool != null) {
>> + pool.offer(object);
>> + }
>> + }
>> +}
>> Index: main/java/com/sun/grizzly/util/ObjectPool.java
>> --- main/java/com/sun/grizzly/util/ObjectPool.java Locally New
>> +++ main/java/com/sun/grizzly/util/ObjectPool.java Locally New
>> @@ -0,0 +1,35 @@
>> +/*
>> + * The contents of this file are subject to the terms
>> + * of the Common Development and Distribution License
>> + * (the License). You may not use this file except in
>> + * compliance with the License.
>> + *
>> + * You can obtain a copy of the license at
>> + * https://glassfish.dev.java.net/public/CDDLv1.0.html or
>> + * glassfish/bootstrap/legal/CDDLv1.0.txt.
>> + * See the License for the specific language governing
>> + * permissions and limitations under the License.
>> + *
>> + * When distributing Covered Code, include this CDDL
>> + * Header Notice in each file and include the License file
>> + * at glassfish/bootstrap/legal/CDDLv1.0.txt.
>> + * If applicable, add the following below the CDDL Header,
>> + * with the fields enclosed by brackets [] replaced by
>> + * you own identifying information:
>> + * "Portions Copyrighted [year] [name of copyright owner]"
>> + *
>> + * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
>> + */
>> +
>> +package com.sun.grizzly.util;
>> +
>> +/**
>> + * Basic interface for object pool implementations
>> + * + * @author Alexey Stashok
>> + */
>> +public interface ObjectPool<E> {
>> + public E poll();
>> +
>> + public void offer(E object);
>> +}
>> Index: main/java/com/sun/grizzly/util/SelectionKeyActionAttachment.java
>> --- main/java/com/sun/grizzly/util/SelectionKeyActionAttachment.java
>> Locally New
>> +++ main/java/com/sun/grizzly/util/SelectionKeyActionAttachment.java
>> Locally New
>> @@ -0,0 +1,50 @@
>> +/*
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + * + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the "License"). You
>> + * may not use this file except in compliance with the License. You
>> can obtain
>> + * a copy of the License at
>> https://glassfish.dev.java.net/public/CDDL+GPL.html
>> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for
>> the specific
>> + * language governing permissions and limitations under the License.
>> + * + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at
>> glassfish/bootstrap/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the "Classpath"
>> exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + * + * Contributor(s):
>> + * + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this file
>> under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL Version
>> 2 code
>> + * and therefore, elected the GPL Version 2 license, then the option
>> applies
>> + * only if the new code is made subject to such option by the copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.grizzly.util;
>> +
>> +import java.nio.channels.SelectionKey;
>> +
>> +/**
>> + * Class represents extended version of
>> <code>SelectionKeyAttachment</code>,
>> + * and introduces process method, which will be called by framework
>> once + * <code>SelectionKey</code> has some ready event, before
>> actual event processing.
>> + * + * @author Alexey Stashok
>> + */
>> +public abstract class SelectionKeyActionAttachment extends
>> SelectionKeyAttachment {
>> + public abstract void process(SelectionKey selectionKey);
>> +}
>> Index: main/java/com/sun/grizzly/util/SelectionKeyAttachment.java
>> --- main/java/com/sun/grizzly/util/SelectionKeyAttachment.java
>> Locally New
>> +++ main/java/com/sun/grizzly/util/SelectionKeyAttachment.java
>> Locally New
>> @@ -0,0 +1,70 @@
>> +/*
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + * + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the "License"). You
>> + * may not use this file except in compliance with the License. You
>> can obtain
>> + * a copy of the License at
>> https://glassfish.dev.java.net/public/CDDL+GPL.html
>> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for
>> the specific
>> + * language governing permissions and limitations under the License.
>> + * + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at
>> glassfish/bootstrap/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the "Classpath"
>> exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + * + * Contributor(s):
>> + * + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this file
>> under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL Version
>> 2 code
>> + * and therefore, elected the GPL Version 2 license, then the option
>> applies
>> + * only if the new code is made subject to such option by the copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.grizzly.util;
>> +
>> +import java.nio.channels.SelectionKey;
>> +
>> +/**
>> + * Basic class for all SelectionKey attachments.
>> + * Custom attachments should be inherited from it.
>> + * + * @author Alexey Stashok
>> + */
>> +public abstract class SelectionKeyAttachment {
>> + private Long timeout;
>> +
>> + public static Object getAttachment(SelectionKey key) {
>> + Object attachment = key.attachment();
>> + if (attachment instanceof SelectionKeyAttachmentWrapper) {
>> + return ((SelectionKeyAttachmentWrapper)
>> attachment).getAttachment();
>> + }
>> + + return attachment;
>> + }
>> + + public Long getTimeout() {
>> + return timeout;
>> + }
>> +
>> + public void setTimeout(Long timeout) {
>> + this.timeout = timeout;
>> + }
>> + + public void release() {
>> + timeout = null;
>> + }
>> +}
>> Index: main/java/com/sun/grizzly/util/SelectionKeyAttachmentWrapper.java
>> --- main/java/com/sun/grizzly/util/SelectionKeyAttachmentWrapper.java
>> Locally New
>> +++ main/java/com/sun/grizzly/util/SelectionKeyAttachmentWrapper.java
>> Locally New
>> @@ -0,0 +1,70 @@
>> +/*
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + * + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the "License"). You
>> + * may not use this file except in compliance with the License. You
>> can obtain
>> + * a copy of the License at
>> https://glassfish.dev.java.net/public/CDDL+GPL.html
>> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for
>> the specific
>> + * language governing permissions and limitations under the License.
>> + * + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at
>> glassfish/bootstrap/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the "Classpath"
>> exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + * + * Contributor(s):
>> + * + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this file
>> under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL Version
>> 2 code
>> + * and therefore, elected the GPL Version 2 license, then the option
>> applies
>> + * only if the new code is made subject to such option by the copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.grizzly.util;
>> +
>> +import java.nio.channels.SelectionKey;
>> +
>> +/**
>> + * <code>SelectionKey</code> attachment utility class.
>> + * This class could be used as wrapper for custom
>> <code>SelectionKey</code>
>> + * attachments, which are not subclasses of
>> <code>SelectionKeyAttachment</code>
>> + * class.
>> + * + * @author Alexey Stashok
>> + */
>> +public class SelectionKeyAttachmentWrapper<E> extends
>> SelectionKeyActionAttachment {
>> + private E attachment;
>> +
>> + public E getAttachment() {
>> + return attachment;
>> + }
>> +
>> + public void setAttachment(E attachment) {
>> + this.attachment = attachment;
>> + }
>> +
>> + @Override
>> + public void process(SelectionKey selectionKey) {
>> + // Do nothing by default
>> + }
>> +
>> + @Override
>> + public void release() {
>> + attachment = null;
>> + super.release();
>> + }
>> +}
>> Index: main/java/com/sun/grizzly/util/SelectionKeyOP.java
>> --- main/java/com/sun/grizzly/util/SelectionKeyOP.java Base (BASE)
>> +++ main/java/com/sun/grizzly/util/SelectionKeyOP.java Locally
>> Modified (Based On LOCAL)
>> @@ -27,7 +27,6 @@
>> import java.net.SocketAddress;
>> import java.nio.channels.SelectableChannel;
>> import java.nio.channels.SelectionKey;
>> -import java.util.concurrent.ConcurrentLinkedQueue;
>>
>> /**
>> *
>> @@ -38,27 +37,29 @@
>> private SelectionKey key;
>> private SelectableChannel channel;
>> - private static ConcurrentLinkedQueue<SelectionKeyOP>
>> readWritePool = - new
>> ConcurrentLinkedQueue<SelectionKeyOP>();
>> + private static ConcurrentLinkedQueuePool<SelectionKeyOP>
>> readWritePool =
>> + new ConcurrentLinkedQueuePool<SelectionKeyOP>() {
>> + @Override
>> + public SelectionKeyOP newInstance() {
>> + return new SelectionKeyOP();
>> + }
>> + };
>> - private static ConcurrentLinkedQueue<SelectionKeyOP>
>> connectPool = - new ConcurrentLinkedQueue<SelectionKeyOP>();
>> + private static ConcurrentLinkedQueuePool<SelectionKeyOP>
>> connectPool =
>> + new ConcurrentLinkedQueuePool<SelectionKeyOP>() {
>> + @Override
>> + public SelectionKeyOP newInstance() {
>> + return new ConnectSelectionKeyOP();
>> + }
>> + };
>> public static SelectionKeyOP aquireSelectionKeyOP(int op) {
>> if (op == SelectionKey.OP_READ || op ==
>> SelectionKey.OP_WRITE ||
>> op == (SelectionKey.OP_WRITE | SelectionKey.OP_READ)) {
>> SelectionKeyOP operation = readWritePool.poll();
>> - if (operation == null) {
>> - operation = new SelectionKeyOP();
>> - }
>> - return operation;
>> } else if (op == SelectionKey.OP_CONNECT) {
>> SelectionKeyOP operation = connectPool.poll();
>> - if (operation == null) {
>> - operation = new ConnectSelectionKeyOP();
>> - }
>> - \ No newline at end of file
>> return operation;
>> }
>> Index:
>> main/java/com/sun/grizzly/util/SSLSelectionKeyAttachment.java
>> --- main/java/com/sun/grizzly/util/SSLSelectionKeyAttachment.java
>> Locally New
>> +++ main/java/com/sun/grizzly/util/SSLSelectionKeyAttachment.java
>> Locally New
>> @@ -0,0 +1,145 @@
>> +/*
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + * + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + * + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the "License"). You
>> + * may not use this file except in compliance with the License. You
>> can obtain
>> + * a copy of the License at
>> https://glassfish.dev.java.net/public/CDDL+GPL.html
>> + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for
>> the specific
>> + * language governing permissions and limitations under the License.
>> + * + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at
>> glassfish/bootstrap/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the "Classpath"
>> exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + * + * Contributor(s):
>> + * + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this file
>> under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL Version
>> 2 code
>> + * and therefore, elected the GPL Version 2 license, then the option
>> applies
>> + * only if the new code is made subject to such option by the copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.grizzly.util;
>> +
>> +import java.nio.ByteBuffer;
>> +import java.nio.channels.SelectionKey;
>> +import javax.net.ssl.SSLEngine;
>> +
>> +/**
>> + * <code>SelectionKeyAttachment</code> implementation, which is
>> targeted for SSL
>> + * support.
>> + * + * @author Alexey Stashok
>> + */
>> +public class SSLSelectionKeyAttachment extends
>> SelectionKeyActionAttachment {
>> +
>> + private static
>> ConcurrentLinkedQueuePool<SSLSelectionKeyAttachment> pool =
>> + new
>> ConcurrentLinkedQueuePool<SSLSelectionKeyAttachment>() {
>> +
>> + @Override
>> + public SSLSelectionKeyAttachment newInstance() {
>> + return new SSLSelectionKeyAttachment();
>> + }
>> + };
>> + private SSLEngine sslEngine;
>> + private ByteBuffer inputBB;
>> + private ByteBuffer outputBB;
>> +
>> + /**
>> + * Saves (if required) secure buffers, associated with
>> <code>SSLEngine</code>
>> + * If secured data, associated with <code>SSLEngine</code>, is
>> not completely
>> + * processed now (may be additional data is required) - then it
>> could be processed
>> + * on next SSLReadFilter execution.
>> + */
>> + public static void attach(SelectionKey key, SSLEngine sslEngine) {
>> + SSLSelectionKeyAttachment attachment = null;
>> + Object currentAttachment = key.attachment();
>> + if (currentAttachment != null &&
>> + currentAttachment instanceof
>> SSLSelectionKeyAttachment) {
>> + attachment = (SSLSelectionKeyAttachment) currentAttachment;
>> + } else {
>> + attachment = pool.poll();
>> + }
>> +
>> + attachment.setInputBB(null);
>> + attachment.setOutputBB(null);
>> +
>> + attachment.setSslEngine(sslEngine);
>> + key.attach(attachment);
>> + }
>> +
>> + public ByteBuffer getInputBB() {
>> + return inputBB;
>> + }
>> +
>> + public void setInputBB(ByteBuffer inputBB) {
>> + this.inputBB = inputBB;
>> + }
>> +
>> + public ByteBuffer getOutputBB() {
>> + return outputBB;
>> + }
>> +
>> + public void setOutputBB(ByteBuffer outputBB) {
>> + this.outputBB = outputBB;
>> + }
>> +
>> + public SSLEngine getSslEngine() {
>> + return sslEngine;
>> + }
>> +
>> + public void setSslEngine(SSLEngine sslEngine) {
>> + this.sslEngine = sslEngine;
>> + }
>> +
>> + /**
>> + * Restores (if required) secure buffers, associated with
>> <code>SSLEngine</code>,
>> + * which were saved during previous SSLReadFilter execution.
>> + * It makes possible data, which wasn't processed on previous
>> cycle to be processed now
>> + */
>> + @Override
>> + public void process(SelectionKey selectionKey) {
>> + WorkerThreadImpl workerThread;
>> + try {
>> + workerThread = (WorkerThreadImpl) Thread.currentThread();
>> + } catch (ClassCastException ex) {
>> + throw new IllegalStateException(ex.getMessage());
>> + }
>> +
>> + if (inputBB != null) {
>> + workerThread.setInputBB(inputBB);
>> + inputBB = null;
>> + }
>> +
>> + if (outputBB != null) {
>> + workerThread.setOutputBB(outputBB);
>> + outputBB = null;
>> + }
>> +
>> + workerThread.setSSLEngine(sslEngine);
>> + }
>> +
>> + @Override
>> + public void release() {
>> + sslEngine = null;
>> + inputBB = null;
>> + outputBB = null;
>> + super.release();
>> + pool.offer(this);
>> + }
>> + }
>> Index: main/java/com/sun/grizzly/util/ThreadAttachment.java
>> --- main/java/com/sun/grizzly/util/ThreadAttachment.java Base (BASE)
>> +++ main/java/com/sun/grizzly/util/ThreadAttachment.java Locally
>> Modified (Based On LOCAL)
>> @@ -23,6 +23,7 @@
>> package com.sun.grizzly.util;
>>
>> import java.nio.ByteBuffer;
>> +import java.nio.channels.SelectionKey;
>> import java.util.WeakHashMap;
>> import javax.net.ssl.SSLEngine;
>>
>> @@ -32,12 +33,9 @@
>> *
>> * @author Jeanfrancois Arcand
>> */
>> -public class ThreadAttachment {
>> +public class ThreadAttachment extends SelectionKeyActionAttachment {
>> - private long timeout;
>> - - private String threadId;
>> @@ -169,22 +167,13 @@
>> this.threadId = threadId;
>> }
>>
>> - /**
>> - * Set the timeout used by the SelectionKeyHandler to times out
>> an idle
>> - * connection.
>> + * SelectionKey attachment processing
>> + * @param selectionKey
>> */
>> - public void setTimeout(long timeout){
>> - this.timeout = timeout;
>> + public void process(SelectionKey selectionKey) {
>> + ((WorkerThread) Thread.currentThread()).attach(
>> + (ThreadAttachment) this);
>> + selectionKey.attach(null);
>> }
>> - - - /**
>> - * Return the timeout used by the SelectionKeyHandler to times
>> out an idle
>> - * connection.
>> - */
>> - public long getTimeout(){
>> - return timeout;
>> }
>> - -}
>> Index: main/java/com/sun/grizzly/util/WorkerThreadImpl.java
>> --- main/java/com/sun/grizzly/util/WorkerThreadImpl.java Base (BASE)
>> +++ main/java/com/sun/grizzly/util/WorkerThreadImpl.java Locally
>> Modified (Based On LOCAL)
>> @@ -294,11 +294,11 @@
>> * @return a new ThreadAttachment
>> */
>> public ThreadAttachment detach(boolean copyState) {
>> - if (threadAttachment == null){
>> + if (threadAttachment == null) {
>> threadAttachment = new ThreadAttachment();
>> }
>> - try{
>> + try {
>> threadAttachment.setByteBuffer(byteBuffer);
>> threadAttachment.setSSLEngine(sslEngine);
>> threadAttachment.setInputBB(inputBB);
>> @@ -308,7 +308,7 @@
>> } finally {
>> // We cannot cache/re-use this object as it might be
>> referenced
>> // by more than one thread. - if (copyState){
>> + if (copyState) {
>> // Re-create a new ByteBuffer
>> byteBuffer = ByteBufferFactory.allocate(byteBufferType,
>> initialByteBufferSize);
>>
>>
>>
>> # This patch file was generated by NetBeans IDE
>> # Following Index: paths are relative to:
>> C:\Projects\Grizzly\trunk\modules\portunif\src
>> # 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: main/java/com/sun/grizzly/portunif/TLSPUPreProcessor.java
>> --- main/java/com/sun/grizzly/portunif/TLSPUPreProcessor.java Base
>> (BASE)
>> +++ main/java/com/sun/grizzly/portunif/TLSPUPreProcessor.java Locally
>> Modified (Based On LOCAL)
>> @@ -26,8 +26,9 @@
>> import com.sun.grizzly.Context;
>> import com.sun.grizzly.Controller;
>> import com.sun.grizzly.SSLConfig;
>> -import com.sun.grizzly.filter.SSLReadFilter;
>> +import com.sun.grizzly.util.SSLSelectionKeyAttachment;
>> import com.sun.grizzly.util.SSLUtils;
>> +import com.sun.grizzly.util.SelectionKeyAttachment;
>> import java.io.EOFException;
>> import java.io.IOException;
>> import java.nio.ByteBuffer;
>> @@ -50,12 +51,7 @@
>> private static final String TMP_DECODED_BUFFER
>> ="TMP_DECODED_BUFFER";
>> - /**
>> - * Decrypted ByteBuffer default size.
>> - */
>> - private final static int appBBSize = 5 * 4096;
>>
>> - /**
>> * The <code>SSLContext</code> associated with the SSL
>> implementation
>> * we are running on.
>> @@ -108,14 +104,14 @@
>>
>> SSLEngine sslEngine = null;
>> - Object attachment = key.attachment();
>> - if (attachment == null || !(attachment instanceof SSLEngine)) {
>> + Object attachment = SelectionKeyAttachment.getAttachment(key);
>> + if (attachment == null || !(attachment instanceof
>> SSLSelectionKeyAttachment)) {
>> sslEngine = sslContext.createSSLEngine();
>> sslEngine.setUseClientMode(false);
>> sslEngine.setNeedClientAuth(needClientAuth);
>> sslEngine.setWantClientAuth(wantClientAuth);
>> } else {
>> - sslEngine = (SSLEngine) attachment;
>> + sslEngine = ((SSLSelectionKeyAttachment)
>> attachment).getSslEngine();
>> }
>> ByteBuffer inputBB =
>> protocolRequest.getSecuredInputByteBuffer();
>> @@ -146,8 +142,7 @@
>> inputBB.put((ByteBuffer) byteBuffer.flip());
>> byteBuffer.clear();
>>
>> - boolean OK = Boolean.TRUE.equals(
>> -
>> sslEngine.getSession().getValue(SSLReadFilter.HANDSHAKE));
>> + boolean OK = sslEngine.getSession().isValid();
>> if (!OK) { // Handshake wasn't completed on prev step
>> HandshakeStatus handshakeStatus =
>> HandshakeStatus.NEED_UNWRAP;
>> @@ -156,8 +151,7 @@
>> byteBuffer = SSLUtils.doHandshake(channel,
>> byteBuffer, inputBB, outputBB, sslEngine,
>> handshakeStatus, SSLUtils.getReadTimeout(),
>> inputBB.position() > 0);
>> -
>> sslEngine.getSession().putValue(SSLReadFilter.HANDSHAKE, true);
>> - key.attach(sslEngine);
>> + SSLSelectionKeyAttachment.attach(key, sslEngine);
>> protocolRequest.setSSLEngine(sslEngine);
>> // set "no available data" for secured output buffer
>> outputBB.limit(outputBB.position());
>> @@ -196,8 +190,6 @@
>> if (byteRead > -1) {
>> byteBuffer = SSLUtils.unwrapAll(byteBuffer, inputBB,
>> sslEngine);
>> protocolRequest.setByteBuffer(byteBuffer);
>> -
>> sslEngine.getSession().putValue(SSLReadFilter.DATA_DECODED,
>> - Boolean.TRUE);
>> } else {
>> throw new EOFException();
>> }
>> Index: test/java/com/sun/grizzly/portunif/SimpleProtocolHandler.java
>> --- test/java/com/sun/grizzly/portunif/SimpleProtocolHandler.java
>> Base (BASE)
>> +++ test/java/com/sun/grizzly/portunif/SimpleProtocolHandler.java
>> Locally Modified (Based On LOCAL)
>> @@ -25,13 +25,14 @@
>>
>> import com.sun.grizzly.Context;
>> import com.sun.grizzly.Controller;
>> +import com.sun.grizzly.util.SSLSelectionKeyAttachment;
>> import com.sun.grizzly.util.OutputWriter;
>> import com.sun.grizzly.util.SSLOutputWriter;
>> +import com.sun.grizzly.util.SelectionKeyAttachment;
>> import java.io.IOException;
>> import java.nio.ByteBuffer;
>> import java.nio.channels.SelectionKey;
>> import java.util.logging.Level;
>> -import javax.net.ssl.SSLEngine;
>>
>> /**
>> * @author Alexey Stashok
>> @@ -78,9 +79,9 @@
>> buffer.position(pos);
>> }
>> - Object attachment =
>> protocolRequest.getSelectionKey().attachment();
>> - if (attachment instanceof SSLEngine) {
>> - protocolRequest.setSSLEngine((SSLEngine) attachment);
>> + Object attachment =
>> SelectionKeyAttachment.getAttachment(protocolRequest.getSelectionKey());
>> + if (attachment instanceof SSLSelectionKeyAttachment) {
>> +
>> protocolRequest.setSSLEngine(((SSLSelectionKeyAttachment)
>> attachment).getSslEngine());
>> allocateBuffers(protocolRequest);
>> } else {
>> protocolRequest.setSSLEngine(null);
>>
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>