dev@grizzly.java.net

Re: Please review -> svn commit: r1841

From: Oleksiy Stashok <Oleksiy.Stashok_at_Sun.COM>
Date: Tue, 25 Nov 2008 16:32:54 +0100

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.

Thanks!!!

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
>