On Nov 25, 2008, at 16:34 , Jeanfrancois Arcand wrote:
> Salut,
>
> Oleksiy Stashok wrote:
>> Looks fine for me.
>> Just it's really bad, that we don't have just single place, where
>> we read or write from channel :(, so the same thing should be done
>> in couple of places.
>
> Agree. We need to fix that in 2.0 :-)
We've that fixed in 2.0 ;)
Alexey.
>
>
>
>> Thanks!!!
>
> Merci!
>
> -- Jeanfrancois
>
>
>> WBR,
>> Alexey.
>> On Nov 25, 2008, at 4:01 , Jeanfrancois Arcand wrote:
>>> Salut,
>>>
>>> feedback appreciated!!
>>>
>>> A+
>>>
>>> -- Jeanfrancois
>>>
>>> -------- Original Message --------
>>> Subject: svn commit: r1841 - trunk/modules/grizzly: . src/main/
>>> java/com/sun/grizzly src/main/java/com/sun/grizzly/async src/main/
>>> java/com/sun/grizzly/filter...
>>> Date: Tue, 25 Nov 2008 02:28:05 +0000
>>> From: jfarcand_at_dev.java.net
>>> Reply-To: commits_at_grizzly.dev.java.net
>>> To: commits_at_grizzly.dev.java.net
>>>
>>> Author: jfarcand
>>> Date: 2008-11-25 02:28:04+0000
>>> New Revision: 1841
>>>
>>> Added:
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> ConnectionCloseHandler.java
>>> Modified:
>>> trunk/modules/grizzly/ (props changed)
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> BaseSelectionKeyHandler.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> SSLConnectorHandler.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> TCPConnectorHandler.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> UDPConnectorHandler.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueReader.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueWriter.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueReader.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueWriter.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> UDPAsyncQueueWriter.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/filter/
>>> ReadFilter.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> InputReader.java
>>> trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> OutputWriter.java
>>>
>>> Log:
>>> Fix for https://grizzly.dev.java.net/issues/show_bug.cgi?id=318
>>> ("be able to get notify when the client close the connection on
>>> his side")
>>>
>>> Add support for being notified when a remote client close an open
>>> connection or when the server close the connection. The new API is
>>> called com.sun.grizzly.util.ConnectionCloseHandler (interface) and
>>> can be configured on any class that extends the
>>> BaseSelectionKeyHandler.
>>>
>>> As an example:
>>>
>>> SelectionKeyHandler skh = new DefaultSelectionKeyHandler();
>>> shk.setConnectionCloseHandler(new ConnectionCloseHandler() {
>>>
>>> public void locallyClosed(SelectionKey key) {
>>> logger.info(key + " is being locally cancelled");
>>> }
>>>
>>> public void remotlyClosed(SelectionKey key) {
>>> logger.fine(key + " is being remotly cancelled (connection
>>> closed)");
>>> }
>>> });
>>>
>>> controller.setSelectionKeyHandler(skh);
>>>
>>>
>>> --This line, and those below, will be ignored--
>>>
>>> _M grizzly
>>> M grizzly/src/main/java/com/sun/grizzly/
>>> TCPConnectorHandler.java
>>> M grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java
>>> M grizzly/src/main/java/com/sun/grizzly/filter/ReadFilter.java
>>> M grizzly/src/main/java/com/sun/grizzly/SSLConnectorHandler.java
>>> M grizzly/src/main/java/com/sun/grizzly/
>>> BaseSelectionKeyHandler.java
>>> M grizzly/src/main/java/com/sun/grizzly/util/InputReader.java
>>> A grizzly/src/main/java/com/sun/grizzly/util/
>>> ConnectionCloseHandler.java
>>> M grizzly/src/main/java/com/sun/grizzly/util/OutputWriter.java
>>> M grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueWriter.java
>>> M grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueReader.java
>>> M grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueWriter.java
>>> M grizzly/src/main/java/com/sun/grizzly/async/
>>> UDPAsyncQueueWriter.java
>>> M grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueReader.java
>>>
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> BaseSelectionKeyHandler.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/BaseSelectionKeyHandler.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/BaseSelectionKeyHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/BaseSelectionKeyHandler.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> BaseSelectionKeyHandler.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> BaseSelectionKeyHandler.java 2008-11-25 02:28:04+0000
>>> @@ -38,6 +38,7 @@
>>>
>>> package com.sun.grizzly;
>>>
>>> +import com.sun.grizzly.util.ConnectionCloseHandler;
>>> import com.sun.grizzly.util.Copyable;
>>> import com.sun.grizzly.util.SelectionKeyActionAttachment;
>>> import com.sun.grizzly.util.SelectionKeyAttachment;
>>> @@ -67,6 +68,20 @@
>>>
>>> protected Logger logger = Controller.logger();
>>>
>>> + private ConnectionCloseHandler cch = new
>>> ConnectionCloseHandler() {
>>> +
>>> + public void locallyClosed(SelectionKey key) {
>>> + if (logger.isLoggable(Level.FINE)){
>>> + logger.fine(key + " is being locally cancelled");
>>> + }
>>> + }
>>> +
>>> + public void remotlyClosed(SelectionKey key) {
>>> + if (logger.isLoggable(Level.FINE)){
>>> + logger.fine(key + " is being remotly cancelled
>>> (connection closed)");
>>> + }
>>> + }
>>> + };
>>>
>>> /**
>>> * Associated {_at_link SelectorHandler}
>>> @@ -209,14 +224,24 @@
>>> if (!keyIsValid(key)) {
>>> return;
>>> }
>>> -
>>> +
>>> closeChannel(key);
>>> -
>>> - clearKeyAttachment(key);
>>> -
>>> + clearKeyAttachment(key);
>>> cancelKey(key);
>>> + cch.locallyClosed(key);
>>> }
>>>
>>> +
>>> + /**
>>> + * Notify a {_at_link ConnectionCloseHandler} that a remote
>>> connection
>>> + * has been closed.
>>> + *
>>> + * @param key a {_at_link Selectionkey}
>>> + */
>>> + public void notifyRemotlyClose(SelectionKey key){
>>> + cch.remotlyClosed(key);
>>> + }
>>> +
>>>
>>> /**
>>> * {_at_inheritDoc}
>>> @@ -278,6 +303,10 @@
>>> }
>>>
>>>
>>> + /**
>>> + * Close the underlying {_at_link SelectableChannel}
>>> + * @param channel
>>> + */
>>> protected void closeChannel(SelectableChannel channel) {
>>> try {
>>> if (channel instanceof SocketChannel) {
>>> @@ -311,4 +340,20 @@
>>> log(Level.FINE, null, ex);
>>> }
>>> }
>>> +
>>> + /**
>>> + * Return the {_at_link ConnectionClosedHandler}.
>>> + * @return the {_at_link ConnectionClosedHandler}
>>> + */
>>> + public ConnectionCloseHandler getConnectionCloseHandler() {
>>> + return cch;
>>> + }
>>> +
>>> + /**
>>> + * Set the the {_at_link ConnectionClosedHandler}
>>> + * @param cch {_at_link ConnectionClosedHandler}
>>> + */
>>> + public void setConnectionCloseHandler(ConnectionCloseHandler
>>> cch) {
>>> + this.cch = cch;
>>> + }
>>> }
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> SSLConnectorHandler.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/SSLConnectorHandler.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/SSLConnectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/SSLConnectorHandler.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> SSLConnectorHandler.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> SSLConnectorHandler.java 2008-11-25 02:28:04+0000
>>> @@ -936,7 +936,18 @@
>>> " securedInputBuffer: " + securedInputBuffer);
>>> }
>>> // Read data to secured buffer
>>> - int bytesRead = socketChannel.read(securedInputBuffer);
>>> + int bytesRead = -1;
>>> +
>>> + try{
>>> + bytesRead = socketChannel.read(securedInputBuffer);
>>> + } finally {
>>> + if (bytesRead == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> +
>>> ((DefaultSelectionKeyHandler
>>> )skh).notifyRemotlyClose(getSelectionKey());
>>> + }
>>> + }
>>> + }
>>>
>>> if (logger.isLoggable(Level.FINE)) {
>>> logger.log(Level.FINE, "SSLConnectorHandler done read" +
>>> @@ -1213,8 +1224,20 @@
>>> private boolean flushSecuredOutputBuffer() throws IOException {
>>> int nWrite = 1;
>>>
>>> - while (nWrite > 0 && securedOutputBuffer.hasRemaining()) {
>>> - nWrite = socketChannel.write(securedOutputBuffer);
>>> + try{
>>> + while (nWrite > 0 &&
>>> securedOutputBuffer.hasRemaining()) {
>>> + nWrite = socketChannel.write(securedOutputBuffer);
>>> + }
>>> + } catch (IOException ex){
>>> + nWrite = -1;
>>> + throw ex;
>>> + } finally{
>>> + if (nWrite == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> +
>>> ((DefaultSelectionKeyHandler
>>> )skh).notifyRemotlyClose(getSelectionKey());
>>> + }
>>> + }
>>> }
>>>
>>> if (securedOutputBuffer.hasRemaining()) {
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> TCPConnectorHandler.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/TCPConnectorHandler.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> TCPConnectorHandler.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> TCPConnectorHandler.java 2008-11-25 02:28:04+0000
>>> @@ -387,7 +387,21 @@
>>> throw new IllegalStateException
>>> ("Non blocking read needs a
>>> CallbackHandler");
>>> }
>>> - int nRead = socketChannel.read(byteBuffer);
>>> + int nRead = -1;
>>> +
>>> + try{
>>> + nRead = socketChannel.read(byteBuffer);
>>> + } catch (IOException ex){
>>> + nRead = -1;
>>> + throw ex;
>>> + } finally {
>>> + if (nRead == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> + ((DefaultSelectionKeyHandler)skh).notifyRemotlyClose(key);
>>> + }
>>> + }
>>> + }
>>>
>>> if (nRead == 0){
>>> selectorHandler.register(key,SelectionKey.OP_READ);
>>> @@ -423,10 +437,22 @@
>>> SelectionKey key =
>>> socketChannel.keyFor(selectorHandler.getSelector());
>>> int nWrite = 1;
>>> int totalWriteBytes = 0;
>>> - while (nWrite > 0 && byteBuffer.hasRemaining()){
>>> - nWrite = socketChannel.write(byteBuffer);
>>> - totalWriteBytes += nWrite;
>>> - }
>>> + try{
>>> + while (nWrite > 0 && byteBuffer.hasRemaining()){
>>> + nWrite = socketChannel.write(byteBuffer);
>>> + totalWriteBytes += nWrite;
>>> + }
>>> + } catch (IOException ex){
>>> + nWrite = -1;
>>> + throw ex;
>>> + } finally {
>>> + if (nWrite == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> + ((DefaultSelectionKeyHandler)skh).notifyRemotlyClose(key);
>>> + }
>>> + }
>>> + }
>>>
>>> if (totalWriteBytes == 0 && byteBuffer.hasRemaining()){
>>> selectorHandler.register(key,SelectionKey.OP_WRITE);
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> UDPConnectorHandler.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/UDPConnectorHandler.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> UDPConnectorHandler.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> UDPConnectorHandler.java 2008-11-25 02:28:04+0000
>>> @@ -316,8 +316,21 @@
>>> inputStream.setSelectionKey(key);
>>> inputStream.setChannelType(
>>> InputReader.ChannelType.DatagramChannel);
>>> - int nRead = inputStream.read(byteBuffer);
>>> - return nRead;
>>> + int nRead = -1;
>>> + try{
>>> + inputStream.read(byteBuffer);
>>> + } catch (IOException ex){
>>> + nRead = -1;
>>> + throw ex;
>>> + } finally {
>>> + if (nRead == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> + ((DefaultSelectionKeyHandler)skh).notifyRemotlyClose(key);
>>> + }
>>> + }
>>> + return nRead;
>>> + }
>>> } else {
>>> if (callbackHandler == null){
>>> throw new IllegalStateException
>>> @@ -353,7 +366,20 @@
>>> ("Non blocking write needs a
>>> CallbackHandler");
>>> }
>>> SelectionKey key =
>>> datagramChannel.keyFor(selectorHandler.getSelector());
>>> - int nWrite = datagramChannel.write(byteBuffer);
>>> + int nWrite = -1;
>>> + try{
>>> + nWrite = datagramChannel.write(byteBuffer);
>>> + } catch (IOException ex){
>>> + nWrite = -1;
>>> + throw ex;
>>> + } finally{
>>> + if (nWrite == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> + ((DefaultSelectionKeyHandler)skh).notifyRemotlyClose(key);
>>> + }
>>> + }
>>> + }
>>>
>>> if (nWrite == 0){
>>> selectorHandler.register(key, SelectionKey.OP_WRITE);
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> async/AbstractAsyncQueueReader.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/AbstractAsyncQueueReader.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/AbstractAsyncQueueReader.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/AbstractAsyncQueueReader.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueReader.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueReader.java 2008-11-25 02:28:04+0000
>>> @@ -60,7 +60,7 @@
>>> * @author oleksiys
>>> */
>>> public abstract class AbstractAsyncQueueReader implements
>>> AsyncQueueReader {
>>> - private SelectorHandler selectorHandler;
>>> + protected SelectorHandler selectorHandler;
>>> private AsyncQueue<SelectableChannel, AsyncReadQueueRecord>
>>> readQueue;
>>> private ConcurrentLinkedQueue<AsyncReadQueueRecord> recordQueue;
>>>
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> async/AbstractAsyncQueueWriter.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/AbstractAsyncQueueWriter.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/AbstractAsyncQueueWriter.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/AbstractAsyncQueueWriter.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueWriter.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> AbstractAsyncQueueWriter.java 2008-11-25 02:28:04+0000
>>> @@ -62,7 +62,7 @@
>>> * @author oleksiys
>>> */
>>> public abstract class AbstractAsyncQueueWriter implements
>>> AsyncQueueWriter {
>>> - private SelectorHandler selectorHandler;
>>> + protected SelectorHandler selectorHandler;
>>> private AsyncQueue<SelectableChannel, AsyncWriteQueueRecord>
>>> writeQueue;
>>> private ConcurrentLinkedQueue<AsyncWriteQueueRecord> recordQueue;
>>>
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> async/TCPAsyncQueueReader.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/TCPAsyncQueueReader.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/TCPAsyncQueueReader.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/TCPAsyncQueueReader.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueReader.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueReader.java 2008-11-25 02:28:04+0000
>>> @@ -38,11 +38,15 @@
>>>
>>> package com.sun.grizzly.async;
>>>
>>> +import com.sun.grizzly.BaseSelectionKeyHandler;
>>> +import com.sun.grizzly.DefaultSelectionKeyHandler;
>>> +import com.sun.grizzly.SelectionKeyHandler;
>>> import com.sun.grizzly.SelectorHandler;
>>> import java.io.EOFException;
>>> import java.io.IOException;
>>> import java.nio.ByteBuffer;
>>> import java.nio.channels.ReadableByteChannel;
>>> +import java.nio.channels.SelectableChannel;
>>> import java.nio.channels.SocketChannel;
>>>
>>> /**
>>> @@ -88,20 +92,32 @@
>>> return dstResult;
>>> }
>>>
>>> - private int doRead(ReadableByteChannel channel,
>>> - ByteBuffer byteBuffer)
>>> + private int doRead(ReadableByteChannel channel,ByteBuffer
>>> byteBuffer)
>>> throws IOException {
>>> int readBytes = 0;
>>> - int lastReadBytes = 0;
>>> - do {
>>> - lastReadBytes = channel.read(byteBuffer);
>>> - if (lastReadBytes > 0) {
>>> - readBytes += lastReadBytes;
>>> - } else if (lastReadBytes == -1 && readBytes == 0) {
>>> - readBytes = -1;
>>> + int lastReadBytes = -1;
>>> + try{
>>> + do {
>>> + lastReadBytes = channel.read(byteBuffer);
>>> + if (lastReadBytes > 0) {
>>> + readBytes += lastReadBytes;
>>> + } else if (lastReadBytes == -1 && readBytes == 0) {
>>> + readBytes = -1;
>>> + }
>>> +
>>> + } while(lastReadBytes > 0 &&
>>> byteBuffer.hasRemaining());
>>> + } catch (IOException ex){
>>> + lastReadBytes = -1;
>>> + throw ex;
>>> + } finally{
>>> + if (lastReadBytes == -1 || readBytes == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> +
>>> ((DefaultSelectionKeyHandler
>>> )skh).notifyRemotlyClose(((SelectableChannel)channel)
>>> + .keyFor(selectorHandler.getSelector()));
>>> + }
>>> }
>>> -
>>> - } while(lastReadBytes > 0 && byteBuffer.hasRemaining());
>>> + }
>>>
>>> return readBytes;
>>> }
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> async/TCPAsyncQueueWriter.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/TCPAsyncQueueWriter.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/TCPAsyncQueueWriter.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/TCPAsyncQueueWriter.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueWriter.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> TCPAsyncQueueWriter.java 2008-11-25 02:28:04+0000
>>> @@ -38,10 +38,15 @@
>>>
>>> package com.sun.grizzly.async;
>>>
>>> +import com.sun.grizzly.BaseSelectionKeyHandler;
>>> +import com.sun.grizzly.DefaultSelectionKeyHandler;
>>> +import com.sun.grizzly.SelectionKeyHandler;
>>> import com.sun.grizzly.SelectorHandler;
>>> +import com.sun.grizzly.util.ConnectionCloseHandler;
>>> import java.io.IOException;
>>> import java.net.SocketAddress;
>>> import java.nio.ByteBuffer;
>>> +import java.nio.channels.SelectableChannel;
>>> import java.nio.channels.SelectionKey;
>>> import java.nio.channels.WritableByteChannel;
>>>
>>> @@ -78,14 +83,26 @@
>>> OperationResult dstResult) throws IOException {
>>> int written = 0;
>>> int lastWriteBytes = 0;
>>> - do {
>>> - lastWriteBytes = channel.write(byteBuffer);
>>> - if (lastWriteBytes > 0) {
>>> - written += lastWriteBytes;
>>> - }
>>> -
>>> - } while(lastWriteBytes > 0 && byteBuffer.hasRemaining());
>>> -
>>> + try{
>>> + do {
>>> + lastWriteBytes = channel.write(byteBuffer);
>>> + if (lastWriteBytes > 0) {
>>> + written += lastWriteBytes;
>>> + }
>>> +
>>> + } while(lastWriteBytes > 0 &&
>>> byteBuffer.hasRemaining());
>>> + } catch (IOException ex){
>>> + lastWriteBytes = -1;
>>> + throw ex;
>>> + } finally {
>>> + if (lastWriteBytes == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> +
>>> ((DefaultSelectionKeyHandler
>>> )skh).notifyRemotlyClose( ((SelectableChannel)channel)
>>> + .keyFor(selectorHandler.getSelector()));
>>> + }
>>> + }
>>> + }
>>> dstResult.bytesProcessed = written;
>>> return dstResult;
>>> }
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> async/UDPAsyncQueueWriter.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/UDPAsyncQueueWriter.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/UDPAsyncQueueWriter.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/UDPAsyncQueueWriter.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> UDPAsyncQueueWriter.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/async/
>>> UDPAsyncQueueWriter.java 2008-11-25 02:28:04+0000
>>> @@ -38,12 +38,17 @@
>>>
>>> package com.sun.grizzly.async;
>>>
>>> +import com.sun.grizzly.BaseSelectionKeyHandler;
>>> +import com.sun.grizzly.DefaultSelectionKeyHandler;
>>> +import com.sun.grizzly.SelectionKeyHandler;
>>> import com.sun.grizzly.SelectorHandler;
>>> +import com.sun.grizzly.util.ConnectionCloseHandler;
>>> import java.io.IOException;
>>> import java.nio.ByteBuffer;
>>> import java.nio.channels.WritableByteChannel;
>>> import java.net.SocketAddress;
>>> import java.nio.channels.DatagramChannel;
>>> +import java.nio.channels.SelectableChannel;
>>>
>>> /**
>>> * UDP implementation of {_at_link AsyncQueueWriter}
>>> @@ -61,19 +66,32 @@
>>> OperationResult dstResult) throws IOException {
>>>
>>> int written = 0;
>>> - int lastWriteBytes = 0;
>>> - do {
>>> - if (dstAddress != null) {
>>> - lastWriteBytes = ((DatagramChannel)
>>> channel).send(byteBuffer, dstAddress);
>>> - } else {
>>> - lastWriteBytes = channel.write(byteBuffer);
>>> - }
>>> -
>>> - if (lastWriteBytes > 0) {
>>> - written += lastWriteBytes;
>>> - }
>>> -
>>> - } while(lastWriteBytes > 0 && byteBuffer.hasRemaining());
>>> + int lastWriteBytes = -1;
>>> + try{
>>> + do {
>>> + if (dstAddress != null) {
>>> + lastWriteBytes = ((DatagramChannel)
>>> channel).send(byteBuffer, dstAddress);
>>> + } else {
>>> + lastWriteBytes = channel.write(byteBuffer);
>>> + }
>>> +
>>> + if (lastWriteBytes > 0) {
>>> + written += lastWriteBytes;
>>> + }
>>> +
>>> + } while(lastWriteBytes > 0 &&
>>> byteBuffer.hasRemaining());
>>> + } catch (IOException ex){
>>> + lastWriteBytes = -1;
>>> + throw ex;
>>> + } finally {
>>> + if (lastWriteBytes == -1){
>>> + SelectionKeyHandler skh =
>>> selectorHandler.getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> +
>>> ((DefaultSelectionKeyHandler
>>> )skh).notifyRemotlyClose( ((SelectableChannel)channel)
>>> + .keyFor(selectorHandler.getSelector()));
>>> + }
>>> + }
>>> + }
>>>
>>> dstResult.bytesProcessed = written;
>>> return dstResult;
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/
>>> filter/ReadFilter.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/filter/ReadFilter.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/filter/ReadFilter.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/filter/ReadFilter.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/filter/
>>> ReadFilter.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/filter/
>>> ReadFilter.java 2008-11-25 02:28:04+0000
>>> @@ -38,6 +38,7 @@
>>>
>>> package com.sun.grizzly.filter;
>>>
>>> +import com.sun.grizzly.BaseSelectionKeyHandler;
>>> import com.sun.grizzly.Context;
>>> import com.sun.grizzly.Controller;
>>> import com.sun.grizzly.ProtocolFilter;
>>> @@ -56,6 +57,7 @@
>>> import com.sun.grizzly.Controller.Protocol;
>>> import com.sun.grizzly.ProtocolChain;
>>> import com.sun.grizzly.ReinvokeAware;
>>> +import com.sun.grizzly.SelectionKeyHandler;
>>> import com.sun.grizzly.SelectorHandler;
>>>
>>> /**
>>> @@ -129,7 +131,7 @@
>>> SocketAddress socketAddress = null;
>>> Exception exception = null;
>>> SelectionKey key = ctx.getSelectionKey();
>>> -
>>> +
>>> Protocol protocol = ctx.getProtocol();
>>> try {
>>> int loop = 0;
>>> @@ -162,6 +164,14 @@
>>> exception = ex;
>>> log("ReadFilter.execute",ex);
>>> } finally {
>>> + SelectionKeyHandler skh =
>>> + ctx.getSelectorHandler().getSelectionKeyHandler();
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> + ((WorkerThread)Thread.currentThread())
>>> + .getAttachment().setAttribute("ConnectionCloseHandler",
>>> + ((BaseSelectionKeyHandler)skh).getConnectionCloseHandler());
>>> + }
>>> +
>>> if (exception != null){
>>> ctx.setAttribute(Context.THROWABLE,exception);
>>> if (protocol != UDP){
>>> @@ -169,10 +179,16 @@
>>> Context.KeyRegistrationState.CANCEL);
>>> }
>>> invokeNextFilter = false;
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> +
>>> ((BaseSelectionKeyHandler)skh).notifyRemotlyClose(key);
>>> + }
>>> } else if (count == -1 && protocol != UDP){
>>> ctx.setKeyRegistrationState(
>>> Context.KeyRegistrationState.CANCEL);
>>> invokeNextFilter = false;
>>> + if (skh instanceof BaseSelectionKeyHandler){
>>> +
>>> ((BaseSelectionKeyHandler)skh).notifyRemotlyClose(key);
>>> + }
>>> } else if (socketAddress == null && protocol == UDP ){
>>> ctx.setKeyRegistrationState(Context.KeyRegistrationState.REGISTER);
>>> invokeNextFilter = false;
>>>
>>> Added: trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> ConnectionCloseHandler.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/ConnectionCloseHandler.java?view=auto&rev=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- (empty file)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> ConnectionCloseHandler.java 2008-11-25 02:28:04+0000
>>> @@ -0,0 +1,73 @@
>>> +/*
>>> + *
>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>>> + *
>>> + * Copyright 2007-2008 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 com.sun.grizzly.Handler;
>>> +import java.nio.channels.SelectionKey;
>>> +
>>> +/**
>>> + * Simple listener to be used when an application needs to be
>>> notified when a
>>> + * a {_at_link SelectorHandler}, {_at_link ConnectionHandler} or {_at_link
>>> SelectionKeyHandler}
>>> + * close a connection ({_at_link
>>> ConnectionCloseHandler#locallyClosed}), or when a
>>> + * remote client close the connection ({_at_link
>>> ConnectionCloseHandler#remotlyClosed}).
>>> + *
>>> + * Note that when the connection is closed remotly, the ({_at_link
>>> ConnectionCloseHandler#remotlyClosed})
>>> + * will be invoked immediately followed by a ({_at_link
>>> ConnectionCloseHandler#locallyClosed}), as
>>> + * Grizzly will discard the server side dirty {_at_link SelectionKey}.
>>> + *
>>> + * @author Jeanfrancois Arcand
>>> + */
>>> +public interface ConnectionCloseHandler extends Handler {
>>> +
>>> + /**
>>> + * Invoked when the a {_at_link SelectionKey} is cancelled
>>> locally, e.g. by
>>> + * one {_at_link SelectorHandler}, {_at_link ConnectionHandler} or
>>> {_at_link SelectionKeyHandler}
>>> + *
>>> + * @param key a {_at_link SelectionKey}
>>> + */
>>> + void locallyClosed(SelectionKey key);
>>> +
>>> +
>>> + /**
>>> + * Invoked when a remote connection is being closed.
>>> + *
>>> + * @param key a {_at_link SelectionKey}
>>> + */
>>> + void remotlyClosed(SelectionKey key);
>>> +
>>> +}
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> InputReader.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/InputReader.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/InputReader.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/InputReader.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> InputReader.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> InputReader.java 2008-11-25 02:28:04+0000
>>> @@ -251,12 +251,30 @@
>>> */
>>> protected int doRead() throws IOException{
>>> if ( key == null ) return -1;
>>> -
>>> - if (secure){
>>> - return doSecureRead();
>>> - } else {
>>> - return doClearRead();
>>> - }
>>> +
>>> + int nRead = -1;
>>> + try{
>>> + if (secure){
>>> + nRead = doSecureRead();
>>> + } else {
>>> + nRead = doClearRead();
>>> + }
>>> + } catch (IOException ex){
>>> + nRead = -1;
>>> + throw ex;
>>> + } finally {
>>> + if (nRead == -1){
>>> + if (Thread.currentThread() instanceof
>>> WorkerThread){
>>> + ConnectionCloseHandler cch =
>>> (ConnectionCloseHandler)
>>> + ((WorkerThread)Thread.currentThread())
>>> + .getAttachment().getAttribute("ConnectionCloseHandler");
>>> + if (cch != null){
>>> + cch.remotlyClosed(key);
>>> + }
>>> + }
>>> + }
>>> + return nRead;
>>> + }
>>> }
>>>
>>>
>>>
>>> Modified: trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> OutputWriter.java
>>> Url: https://grizzly.dev.java.net/source/browse/grizzly/trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/OutputWriter.java?view=diff&rev=1841&p1=trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/OutputWriter.java&p2=trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/OutputWriter.java&r1=1840&r2=1841
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> =
>>> ====================================================================
>>> --- trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> OutputWriter.java (original)
>>> +++ trunk/modules/grizzly/src/main/java/com/sun/grizzly/util/
>>> OutputWriter.java 2008-11-25 02:28:04+0000
>>> @@ -98,14 +98,15 @@
>>> SelectionKey key = null;
>>> Selector writeSelector = null;
>>> int attempts = 0;
>>> - int bytesProduced = 0;
>>> + int nWrite = 0;
>>> + int len = -1;
>>> try {
>>> WritableByteChannel writableChannel =
>>> (WritableByteChannel) channel;
>>> while ( bb.hasRemaining() ) {
>>> - int len = writableChannel.write(bb);
>>> + len = writableChannel.write(bb);
>>> if (len > 0){
>>> attempts = 0;
>>> - bytesProduced += len;
>>> + nWrite += len;
>>> } else {
>>> attempts++;
>>> if ( writeSelector == null ){
>>> @@ -124,6 +125,9 @@
>>> }
>>> }
>>> }
>>> + } catch (IOException ex){
>>> + len = -1;
>>> + throw ex;
>>> } finally {
>>> if (key != null) {
>>> key.cancel();
>>> @@ -134,8 +138,19 @@
>>> // Cancel the key.
>>>
>>> SelectorFactory.selectNowAndReturnSelector(writeSelector);
>>> }
>>> +
>>> + if (len == -1){
>>> + if (Thread.currentThread() instanceof
>>> WorkerThread){
>>> + ConnectionCloseHandler cch =
>>> (ConnectionCloseHandler)
>>> + ((WorkerThread)Thread.currentThread())
>>> + .getAttachment().getAttribute("ConnectionCloseHandler");
>>> + if (cch != null){
>>> + cch.remotlyClosed(key);
>>> + }
>>> + }
>>> + }
>>> }
>>> - return bytesProduced;
>>> + return nWrite;
>>> }
>>>
>>>
>>> @@ -181,13 +196,14 @@
>>> totalBytes += aBb.remaining();
>>> }
>>>
>>> - long bytesProduced = 0;
>>> + long nWrite = 0;
>>> + long len = -1;
>>> try {
>>> - while (bytesProduced < totalBytes ) {
>>> - long len = socketChannel.write(bb);
>>> + while (nWrite < totalBytes ) {
>>> + len = socketChannel.write(bb);
>>> if (len > 0){
>>> attempts = 0;
>>> - bytesProduced += len;
>>> + nWrite += len;
>>> } else {
>>> if ( writeSelector == null ){
>>> writeSelector =
>>> SelectorFactory.getSelector();
>>> @@ -206,6 +222,9 @@
>>> }
>>> }
>>> }
>>> + } catch (IOException ex){
>>> + len = -1;
>>> + throw ex;
>>> } finally {
>>> if (key != null) {
>>> key.cancel();
>>> @@ -216,8 +235,19 @@
>>> // Cancel the key.
>>>
>>> SelectorFactory.selectNowAndReturnSelector(writeSelector);
>>> }
>>> +
>>> + if (len == -1){
>>> + if (Thread.currentThread() instanceof
>>> WorkerThread){
>>> + ConnectionCloseHandler cch =
>>> (ConnectionCloseHandler)
>>> + ((WorkerThread)Thread.currentThread())
>>> + .getAttachment().getAttribute("ConnectionCloseHandler");
>>> + if (cch != null){
>>> + cch.remotlyClosed(key);
>>> + }
>>> + }
>>> + }
>>> }
>>> - return bytesProduced;
>>> + return nWrite;
>>> }
>>>
>>>
>>> @@ -267,13 +297,13 @@
>>> SelectionKey key = null;
>>> Selector writeSelector = null;
>>> int attempts = 0;
>>> - int bytesProduced = 0;
>>> + int nWrite = 0;
>>> try {
>>> while ( bb.hasRemaining() ) {
>>> int len = datagramChannel.send(bb,socketAddress);
>>> if (len > 0){
>>> attempts = 0;
>>> - bytesProduced += len;
>>> + nWrite += len;
>>> } else {
>>> if ( writeSelector == null ){
>>> writeSelector =
>>> SelectorFactory.getSelector();
>>> @@ -305,7 +335,7 @@
>>>
>>> SelectorFactory.selectNowAndReturnSelector(writeSelector);
>>> }
>>> }
>>> - return bytesProduced;
>>> + return nWrite;
>>> }
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: commits-unsubscribe_at_grizzly.dev.java.net
>>> For additional commands, e-mail: commits-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
>>>
>> ---------------------------------------------------------------------
>> 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
>