diff --git a/pom.xml b/pom.xml index 0819637a90..1bb5596424 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ io.netty netty bundle - 3.5.1.Final-SNAPSHOT + 3.5.0.Final-SNAPSHOT The Netty Project http://netty.io/ @@ -577,10 +577,10 @@ ${project.name} API Reference (${project.version}) ${project.name} API Reference (${project.version}) - -link http://docs.oracle.com/javase/7/docs/api/ + -link http://java.sun.com/javase/6/docs/api/ -link http://code.google.com/apis/protocolbuffers/docs/reference/java/ - -link http://docs.oracle.com/javaee/6/api/ - -link http://www.osgi.org/javadoc/r4v43/core/ + -link http://java.sun.com/products/servlet/2.5/docs/servlet-2_5-mr2/ + -link http://www.osgi.org/javadoc/r4v41/ -link http://www.slf4j.org/apidocs/ -link http://commons.apache.org/logging/commons-logging-1.1.1/apidocs/ -link http://logging.apache.org/log4j/1.2/apidocs/ @@ -665,7 +665,7 @@ ${project.groupId} netty-build - 9 + 7 diff --git a/src/assembly/default.xml b/src/assembly/default.xml index 102ccf4a64..b19ee3b933 100644 --- a/src/assembly/default.xml +++ b/src/assembly/default.xml @@ -34,7 +34,6 @@ **/src/** - **/bin/** **/target/** **/.*/** diff --git a/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java b/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java index 28d75f8b94..5dd845b07b 100644 --- a/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java +++ b/src/main/java/org/jboss/netty/bootstrap/ClientBootstrap.java @@ -231,13 +231,12 @@ public class ClientBootstrap extends Bootstrap { } /** - * Attempts to bind a channel with the specified {@code localAddress}. later the channel can - * be connected to a remoteAddress by calling {@link Channel#connect(SocketAddress)}.This method - * is useful where bind and connect need to be done in separate steps. + * Attempts to bind a channel with the specified {@code localAddress}. later the channel can be connected + * to a remoteAddress by calling {@link Channel#connect(SocketAddress)}.This method is useful where bind and connect + * need to be done in separate steps. * * This can also be useful if you want to set an attachment to the {@link Channel} via - * {@link Channel#setAttachment(Object)} so you can use it after the {@link #bind(SocketAddress)} - * was done. + * {@link Channel#setAttachment(Object)} so you can use it after the {@link #bind(SocketAddress)} was done. *
* For example: * diff --git a/src/main/java/org/jboss/netty/buffer/ChannelBuffer.java b/src/main/java/org/jboss/netty/buffer/ChannelBuffer.java index 50889b6fcd..505f450ebb 100644 --- a/src/main/java/org/jboss/netty/buffer/ChannelBuffer.java +++ b/src/main/java/org/jboss/netty/buffer/ChannelBuffer.java @@ -39,10 +39,11 @@ import java.nio.charset.UnsupportedCharsetException; *

Random Access Indexing

* * Just like an ordinary primitive byte array, {@link ChannelBuffer} uses - * zero-based indexing. - * It means the index of the first byte is always {@code 0} and the index of the last byte is - * always {@link #capacity() capacity - 1}. For example, to iterate all bytes of a buffer, you - * can do the following, regardless of its internal implementation: + * zero-based indexing. + * It means the index of the first byte is always {@code 0} and the index of + * the last byte is always {@link #capacity() capacity - 1}. For example, to + * iterate all bytes of a buffer, you can do the following, regardless of + * its internal implementation: * *
  * {@link ChannelBuffer} buffer = ...;
@@ -1723,15 +1724,13 @@ public interface ChannelBuffer extends Comparable {
             String charsetName, ChannelBufferIndexFinder terminatorFinder);
 
     /**
-     * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and
-     * {@link #toString(int, int, Charset)} instead.
+     * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
      */
     @Deprecated
     String toString(int index, int length, String charsetName);
 
     /**
-     * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and
-     * {@link #toString(int, int, Charset)} instead.
+     * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
      */
     @Deprecated
     String toString(
diff --git a/src/main/java/org/jboss/netty/buffer/ChannelBuffers.java b/src/main/java/org/jboss/netty/buffer/ChannelBuffers.java
index 2995542dc6..df0413ada8 100644
--- a/src/main/java/org/jboss/netty/buffer/ChannelBuffers.java
+++ b/src/main/java/org/jboss/netty/buffer/ChannelBuffers.java
@@ -227,8 +227,7 @@ public final class ChannelBuffers {
      * More accurate estimation yields less unexpected reallocation overhead.
      * The new buffer's {@code readerIndex} and {@code writerIndex} are {@code 0}.
      */
-    public static ChannelBuffer dynamicBuffer(
-            ByteOrder endianness, int estimatedLength, ChannelBufferFactory factory) {
+    public static ChannelBuffer dynamicBuffer(ByteOrder endianness, int estimatedLength, ChannelBufferFactory factory) {
         return new DynamicChannelBuffer(endianness, estimatedLength, factory);
     }
 
@@ -309,8 +308,7 @@ public final class ChannelBuffers {
             return EMPTY_BUFFER;
         }
         if (buffer.hasArray()) {
-            return wrappedBuffer(
-                    buffer.order(), buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
+            return wrappedBuffer(buffer.order(), buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
         } else {
             return new ByteBufferBackedChannelBuffer(buffer);
         }
@@ -387,7 +385,7 @@ public final class ChannelBuffers {
      * Creates a new composite buffer which wraps the readable bytes of the
      * specified buffers without copying them.  A modification on the content
      * of the specified buffers will be visible to the returned buffer.
-     *
+     * 
      * @throws IllegalArgumentException
      *         if the specified buffers' endianness are different from each
      *         other
@@ -401,7 +399,7 @@ public final class ChannelBuffers {
      * of the specified buffers will be visible to the returned buffer.
      * If gathering is true then gathering writes will be used when ever
      * possible.
-     *
+     * 
      * @throws IllegalArgumentException
      *         if the specified buffers' endianness are different from each
      *         other
@@ -446,7 +444,7 @@ public final class ChannelBuffers {
         }
         return EMPTY_BUFFER;
     }
-
+    
 
     /**
      * Creates a new composite buffer which wraps the slices of the specified
@@ -1052,8 +1050,7 @@ public final class ChannelBuffers {
      * The default implementation of {@link ChannelBuffer#indexOf(int, int, ChannelBufferIndexFinder)}.
      * This method is useful when implementing a new buffer type.
      */
-    public static int indexOf(
-            ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
+    public static int indexOf(ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
         if (fromIndex <= toIndex) {
             return firstIndexOf(buffer, fromIndex, toIndex, indexFinder);
         } else {
@@ -1121,8 +1118,7 @@ public final class ChannelBuffers {
         return -1;
     }
 
-    private static int firstIndexOf(
-            ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
+    private static int firstIndexOf(ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
         fromIndex = Math.max(fromIndex, 0);
         if (fromIndex >= toIndex || buffer.capacity() == 0) {
             return -1;
@@ -1137,8 +1133,7 @@ public final class ChannelBuffers {
         return -1;
     }
 
-    private static int lastIndexOf(
-            ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
+    private static int lastIndexOf(ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
         fromIndex = Math.min(fromIndex, buffer.capacity());
         if (fromIndex < 0 || buffer.capacity() == 0) {
             return -1;
diff --git a/src/main/java/org/jboss/netty/buffer/CompositeChannelBuffer.java b/src/main/java/org/jboss/netty/buffer/CompositeChannelBuffer.java
index 3c84532832..9a014ee481 100644
--- a/src/main/java/org/jboss/netty/buffer/CompositeChannelBuffer.java
+++ b/src/main/java/org/jboss/netty/buffer/CompositeChannelBuffer.java
@@ -48,13 +48,13 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
     }
 
     /**
-     * Return true if gathering writes / reads should be used
+     * Return true if gathering writes / reads should be used 
      * for this {@link CompositeChannelBuffer}
      */
     public boolean useGathering() {
         return gathering && DetectionUtil.javaVersion() >= 7;
     }
-
+    
     /**
      * Same with {@link #slice(int, int)} except that this method returns a list.
      */
@@ -140,7 +140,7 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
 
     private CompositeChannelBuffer(CompositeChannelBuffer buffer) {
         order = buffer.order;
-        gathering = buffer.gathering;
+        this.gathering = buffer.gathering;
         components = buffer.components.clone();
         indices = buffer.indices.clone();
         setIndex(buffer.readerIndex(), buffer.writerIndex());
diff --git a/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java b/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java
index 178e098fef..0223e303fb 100644
--- a/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java
+++ b/src/main/java/org/jboss/netty/buffer/DirectChannelBufferFactory.java
@@ -56,11 +56,11 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
 
     private final Object bigEndianLock = new Object();
     private final Object littleEndianLock = new Object();
-    private final int preallocatedBufCapacity;
-    private ChannelBuffer preallocatedBEBuf;
-    private int preallocatedBEBufPos;
-    private ChannelBuffer preallocatedLEBuf;
-    private int preallocatedLEBufPos;
+    private final int preallocatedBufferCapacity;
+    private ChannelBuffer preallocatedBigEndianBuffer;
+    private int preallocatedBigEndianBufferPosition;
+    private ChannelBuffer preallocatedLittleEndianBuffer;
+    private int preallocatedLittleEndianBufferPosition;
 
     /**
      * Creates a new factory whose default {@link ByteOrder} is
@@ -96,10 +96,10 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
         super(defaultOrder);
         if (preallocatedBufferCapacity <= 0) {
             throw new IllegalArgumentException(
-                    "preallocatedBufCapacity must be greater than 0: " + preallocatedBufferCapacity);
+                    "preallocatedBufferCapacity must be greater than 0: " + preallocatedBufferCapacity);
         }
 
-        this.preallocatedBufCapacity = preallocatedBufferCapacity;
+        this.preallocatedBufferCapacity = preallocatedBufferCapacity;
     }
 
     public ChannelBuffer getBuffer(ByteOrder order, int capacity) {
@@ -112,7 +112,7 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
         if (capacity == 0) {
             return ChannelBuffers.EMPTY_BUFFER;
         }
-        if (capacity >= preallocatedBufCapacity) {
+        if (capacity >= preallocatedBufferCapacity) {
             return ChannelBuffers.directBuffer(order, capacity);
         }
 
@@ -160,17 +160,17 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
     private ChannelBuffer allocateBigEndianBuffer(int capacity) {
         ChannelBuffer slice;
         synchronized (bigEndianLock) {
-            if (preallocatedBEBuf == null) {
-                preallocatedBEBuf = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufCapacity);
-                slice = preallocatedBEBuf.slice(0, capacity);
-                preallocatedBEBufPos = capacity;
-            } else if (preallocatedBEBuf.capacity() - preallocatedBEBufPos >= capacity) {
-                slice = preallocatedBEBuf.slice(preallocatedBEBufPos, capacity);
-                preallocatedBEBufPos += capacity;
+            if (preallocatedBigEndianBuffer == null) {
+                preallocatedBigEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufferCapacity);
+                slice = preallocatedBigEndianBuffer.slice(0, capacity);
+                preallocatedBigEndianBufferPosition = capacity;
+            } else if (preallocatedBigEndianBuffer.capacity() - preallocatedBigEndianBufferPosition >= capacity) {
+                slice = preallocatedBigEndianBuffer.slice(preallocatedBigEndianBufferPosition, capacity);
+                preallocatedBigEndianBufferPosition += capacity;
             } else {
-                preallocatedBEBuf = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufCapacity);
-                slice = preallocatedBEBuf.slice(0, capacity);
-                preallocatedBEBufPos = capacity;
+                preallocatedBigEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufferCapacity);
+                slice = preallocatedBigEndianBuffer.slice(0, capacity);
+                preallocatedBigEndianBufferPosition = capacity;
             }
         }
         return slice;
@@ -179,17 +179,17 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
     private ChannelBuffer allocateLittleEndianBuffer(int capacity) {
         ChannelBuffer slice;
         synchronized (littleEndianLock) {
-            if (preallocatedLEBuf == null) {
-                preallocatedLEBuf = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufCapacity);
-                slice = preallocatedLEBuf.slice(0, capacity);
-                preallocatedLEBufPos = capacity;
-            } else if (preallocatedLEBuf.capacity() - preallocatedLEBufPos >= capacity) {
-                slice = preallocatedLEBuf.slice(preallocatedLEBufPos, capacity);
-                preallocatedLEBufPos += capacity;
+            if (preallocatedLittleEndianBuffer == null) {
+                preallocatedLittleEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufferCapacity);
+                slice = preallocatedLittleEndianBuffer.slice(0, capacity);
+                preallocatedLittleEndianBufferPosition = capacity;
+            } else if (preallocatedLittleEndianBuffer.capacity() - preallocatedLittleEndianBufferPosition >= capacity) {
+                slice = preallocatedLittleEndianBuffer.slice(preallocatedLittleEndianBufferPosition, capacity);
+                preallocatedLittleEndianBufferPosition += capacity;
             } else {
-                preallocatedLEBuf = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufCapacity);
-                slice = preallocatedLEBuf.slice(0, capacity);
-                preallocatedLEBufPos = capacity;
+                preallocatedLittleEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufferCapacity);
+                slice = preallocatedLittleEndianBuffer.slice(0, capacity);
+                preallocatedLittleEndianBufferPosition = capacity;
             }
         }
         return slice;
diff --git a/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java b/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java
index ccfe617240..e0a7d282ab 100644
--- a/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java
+++ b/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java
@@ -59,8 +59,7 @@ package org.jboss.netty.channel;
  * 

* Caution: *

- * Use the *Later(..) methods of the {@link Channels} class if you want to send an upstream event - * from a {@link ChannelDownstreamHandler} otherwise you may run into threading issues. + * Use the *Later(..) methods of the {@link Channels} class if you want to send an upstream event from a {@link ChannelDownstreamHandler} otherwise you may run into threading issues. * *

State management

* diff --git a/src/main/java/org/jboss/netty/channel/ChannelEvent.java b/src/main/java/org/jboss/netty/channel/ChannelEvent.java index 50abd6bbb0..83b297171f 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelEvent.java +++ b/src/main/java/org/jboss/netty/channel/ChannelEvent.java @@ -71,8 +71,7 @@ import org.jboss.netty.channel.socket.ServerSocketChannel; * {@code "channelOpen"} * {@link ChannelStateEvent}
(state = {@link ChannelState#OPEN OPEN}, value = {@code true}) * a {@link Channel} is open, but not bound nor connected - * Be aware that this event is fired from within the Boss-Thread so you should not - * execute any heavy operation in there as it will block the dispatching to other workers! + * Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers! * * * {@code "channelClosed"} @@ -83,8 +82,7 @@ import org.jboss.netty.channel.socket.ServerSocketChannel; * {@code "channelBound"} * {@link ChannelStateEvent}
(state = {@link ChannelState#BOUND BOUND}, value = {@link SocketAddress}) * a {@link Channel} is open and bound to a local address, but not connected. - * Be aware that this event is fired from within the Boss-Thread so you should not - * execute any heavy operation in there as it will block the dispatching to other workers! + * Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers! * * * {@code "channelUnbound"} @@ -93,11 +91,9 @@ import org.jboss.netty.channel.socket.ServerSocketChannel; * * * {@code "channelConnected"} - * {@link ChannelStateEvent}
(state = {@link ChannelState#CONNECTED CONNECTED}, value = - * {@link SocketAddress}) + * {@link ChannelStateEvent}
(state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress}) * a {@link Channel} is open, bound to a local address, and connected to a remote address - * Be aware that this event is fired from within the Boss-Thread so you should not - * execute any heavy operation in there as it will block the dispatching to other workers! + * Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers! * * * {@code "writeComplete"} @@ -157,8 +153,7 @@ import org.jboss.netty.channel.socket.ServerSocketChannel; * * * {@code "connect"} - * {@link ChannelStateEvent}
(state = {@link ChannelState#CONNECTED CONNECTED}, value = - * {@link SocketAddress}) + * {@link ChannelStateEvent}
(state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress}) * Connect the {@link Channel} to the specified remote address. * * diff --git a/src/main/java/org/jboss/netty/channel/ChannelHandler.java b/src/main/java/org/jboss/netty/channel/ChannelHandler.java index 31c163385b..300348cb6c 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelHandler.java +++ b/src/main/java/org/jboss/netty/channel/ChannelHandler.java @@ -142,7 +142,7 @@ import org.jboss.netty.channel.group.ChannelGroup; *
  * public final class DataServerState {
  *
- *     public static final {@link ChannelLocal}<Boolean> loggedIn = new {@link ChannelLocal}<>() {
+ *     public static final {@link ChannelLocal}<Boolean> loggedIn = new {@link ChannelLocal}<Boolean>() {
  *         protected Boolean initialValue(Channel channel) {
  *             return false;
  *         }
diff --git a/src/main/java/org/jboss/netty/channel/ChannelLocal.java b/src/main/java/org/jboss/netty/channel/ChannelLocal.java
index 123469f810..a7aa23a04d 100644
--- a/src/main/java/org/jboss/netty/channel/ChannelLocal.java
+++ b/src/main/java/org/jboss/netty/channel/ChannelLocal.java
@@ -48,8 +48,7 @@ public class ChannelLocal implements Iterable> {
     private final boolean removeOnClose;
 
     /**
-     * Creates a {@link Channel} local variable by calling {@link #ChannelLocal(boolean)} with
-     * false as parameter
+     * Creates a {@link Channel} local variable by calling {@link #ChannelLocal(boolean)} with false as parameter
      */
     public ChannelLocal() {
         this(false);
@@ -58,8 +57,7 @@ public class ChannelLocal implements Iterable> {
     /**
      * Creates a {@link Channel} local variable.
      *
-     * @param removeOnClose if true the {@link ChannelLocal} will remove a
-     *                      {@link Channel} from it own once the {@link Channel} was closed.
+     * @param removeOnClose if true the {@link ChannelLocal} will remove a {@link Channel} from it own once the {@link Channel} was closed.
      */
     public ChannelLocal(boolean removeOnClose) {
         this.removeOnClose = removeOnClose;
diff --git a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java
index 7bc033b75e..8a3de0266c 100644
--- a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java
+++ b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java
@@ -168,8 +168,7 @@ import org.jboss.netty.handler.ssl.SslHandler;
  * {@link ChannelPipeline} pipeline = {@link Channels#pipeline() Channels.pipeline()};
  * pipeline.addLast("decoder", new MyProtocolDecoder());
  * pipeline.addLast("encoder", new MyProtocolEncoder());
- * pipeline.addLast("executor", new {@link ExecutionHandler}(
- *         new {@link OrderedMemoryAwareThreadPoolExecutor}(16, 1048576, 1048576)));
+ * pipeline.addLast("executor", new {@link ExecutionHandler}(new {@link OrderedMemoryAwareThreadPoolExecutor}(16, 1048576, 1048576)));
  * pipeline.addLast("handler", new MyBusinessLogicHandler());
  * 
* diff --git a/src/main/java/org/jboss/netty/channel/ChannelState.java b/src/main/java/org/jboss/netty/channel/ChannelState.java index 3aefd47073..3d14438038 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelState.java +++ b/src/main/java/org/jboss/netty/channel/ChannelState.java @@ -29,60 +29,46 @@ import java.net.SocketAddress; * DirectionStateValueMeaning * * - * Upstream{@link #OPEN} - * {@code true}The channel is open. + * Upstream{@link #OPEN}{@code true}The channel is open. * * - * Upstream{@link #OPEN} - * {@code false}The channel is closed. + * Upstream{@link #OPEN}{@code false}The channel is closed. * * - * Upstream{@link #BOUND} - * {@link SocketAddress}The channel is bound to a local address. + * Upstream{@link #BOUND}{@link SocketAddress}The channel is bound to a local address. * * - * Upstream{@link #BOUND} - * {@code null}The channel is unbound to a local address. + * Upstream{@link #BOUND}{@code null}The channel is unbound to a local address. * * - * Upstream{@link #CONNECTED} - * {@link SocketAddress}The channel is connected to a remote address. + * Upstream{@link #CONNECTED}{@link SocketAddress}The channel is connected to a remote address. * * - * Upstream{@link #CONNECTED} - * {@code null}The channel is disconnected from a remote address. + * Upstream{@link #CONNECTED}{@code null}The channel is disconnected from a remote address. * * - * Upstream{@link #INTEREST_OPS} - * an integerThe channel interestOps has been changed. + * Upstream{@link #INTEREST_OPS}an integerThe channel interestOps has been changed. * * - * Downstream{@link #OPEN} - * {@code true}N/A + * Downstream{@link #OPEN}{@code true}N/A * * - * Downstream{@link #OPEN} - * {@code false}Close the channel. + * Downstream{@link #OPEN}{@code false}Close the channel. * * - * Downstream{@link #BOUND} - * {@link SocketAddress}Bind the channel to the specified local address. + * Downstream{@link #BOUND}{@link SocketAddress}Bind the channel to the specified local address. * * - * Downstream{@link #BOUND} - * {@code null}Unbind the channel from the current local address. + * Downstream{@link #BOUND}{@code null}Unbind the channel from the current local address. * * - * Downstream{@link #CONNECTED} - * {@link SocketAddress}Connect the channel to the specified remote address. + * Downstream{@link #CONNECTED}{@link SocketAddress}Connect the channel to the specified remote address. * * - * Downstream{@link #CONNECTED} - * {@code null}Disconnect the channel from the current remote address. + * Downstream{@link #CONNECTED}{@code null}Disconnect the channel from the current remote address. * * - * Downstream{@link #INTEREST_OPS} - * an integerChange the interestOps of the channel. + * Downstream{@link #INTEREST_OPS}an integerChange the interestOps of the channel. * * *

diff --git a/src/main/java/org/jboss/netty/channel/SimpleChannelDownstreamHandler.java b/src/main/java/org/jboss/netty/channel/SimpleChannelDownstreamHandler.java index 6bb571e5a9..d5b69608b3 100644 --- a/src/main/java/org/jboss/netty/channel/SimpleChannelDownstreamHandler.java +++ b/src/main/java/org/jboss/netty/channel/SimpleChannelDownstreamHandler.java @@ -52,8 +52,7 @@ import java.net.SocketAddress; *

* Caution: *

- * Use the *Later(..) methods of the {@link Channels} class if you want to send an upstream event - * from a {@link ChannelDownstreamHandler} otherwise you may run into threading issues. + * Use the *Later(..) methods of the {@link Channels} class if you want to send an upstream event from a {@link ChannelDownstreamHandler} otherwise you may run into threading issues. * */ public class SimpleChannelDownstreamHandler implements ChannelDownstreamHandler { diff --git a/src/main/java/org/jboss/netty/channel/SimpleChannelUpstreamHandler.java b/src/main/java/org/jboss/netty/channel/SimpleChannelUpstreamHandler.java index 78321bb61e..d94855b55b 100644 --- a/src/main/java/org/jboss/netty/channel/SimpleChannelUpstreamHandler.java +++ b/src/main/java/org/jboss/netty/channel/SimpleChannelUpstreamHandler.java @@ -147,8 +147,7 @@ public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler { * Invoked when a {@link Channel} is open, but not bound nor connected. *
* - * Be aware that this event is fired from within the Boss-Thread so you should not - * execute any heavy operation in there as it will block the dispatching to other workers! + * Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers! */ public void channelOpen( ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { @@ -160,8 +159,7 @@ public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler { * but not connected. *
* - * Be aware that this event is fired from within the Boss-Thread so you should not - * execute any heavy operation in there as it will block the dispatching to other workers! + * Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers! */ public void channelBound( ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { @@ -173,8 +171,7 @@ public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler { * connected to a remote address. *
* - * Be aware that this event is fired from within the Boss-Thread so you should not - * execute any heavy operation in there as it will block the dispatching to other workers! + * Be aware that this event is fired from within the Boss-Thread so you should not execute any heavy operation in there as it will block the dispatching to other workers! */ public void channelConnected( ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { diff --git a/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java b/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java index c0e7ee359e..d73d2f9172 100644 --- a/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java +++ b/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java @@ -55,9 +55,7 @@ final class DefaultLocalChannel extends AbstractChannel implements LocalChannel volatile LocalAddress localAddress; volatile LocalAddress remoteAddress; - DefaultLocalChannel( - LocalServerChannel parent, ChannelFactory factory, ChannelPipeline pipeline, - ChannelSink sink, DefaultLocalChannel pairedChannel) { + DefaultLocalChannel(LocalServerChannel parent, ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink, DefaultLocalChannel pairedChannel) { super(parent, factory, pipeline, sink); this.pairedChannel = pairedChannel; config = new DefaultChannelConfig(); diff --git a/src/main/java/org/jboss/netty/channel/local/DefaultLocalServerChannelFactory.java b/src/main/java/org/jboss/netty/channel/local/DefaultLocalServerChannelFactory.java index cc7471405b..c47832ee3a 100644 --- a/src/main/java/org/jboss/netty/channel/local/DefaultLocalServerChannelFactory.java +++ b/src/main/java/org/jboss/netty/channel/local/DefaultLocalServerChannelFactory.java @@ -43,8 +43,8 @@ public class DefaultLocalServerChannelFactory implements LocalServerChannelFacto /** - * Release all the previous created channels. - * This takes care of calling {@link LocalChannelRegistry#unregister(LocalAddress)} for each of them. + * Release all the previous created channels. This takes care of calling {@link LocalChannelRegistry#unregister(LocalAddress)} + * for each if them. */ public void releaseExternalResources() { group.close().awaitUninterruptibly(); diff --git a/src/main/java/org/jboss/netty/channel/socket/ChannelRunnableWrapper.java b/src/main/java/org/jboss/netty/channel/socket/ChannelRunnableWrapper.java index 9ae7f37369..494ccd0e33 100644 --- a/src/main/java/org/jboss/netty/channel/socket/ChannelRunnableWrapper.java +++ b/src/main/java/org/jboss/netty/channel/socket/ChannelRunnableWrapper.java @@ -1,58 +1,58 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.DefaultChannelFuture; - -public class ChannelRunnableWrapper extends DefaultChannelFuture implements Runnable { - - private final Runnable task; - private boolean started; - - public ChannelRunnableWrapper(Channel channel, Runnable task) { - super(channel, true); - this.task = task; - } - - - public void run() { - synchronized (this) { - if (!isCancelled()) { - started = true; - } else { - return; - } - } - try { - task.run(); - setSuccess(); - } catch (Throwable t) { - setFailure(t); - } - } - - @Override - public synchronized boolean cancel() { - if (started) { - return false; - } - return super.cancel(); - } - - - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.DefaultChannelFuture; + +public class ChannelRunnableWrapper extends DefaultChannelFuture implements Runnable { + + private final Runnable task; + private boolean started; + + public ChannelRunnableWrapper(Channel channel, Runnable task) { + super(channel, true); + this.task = task; + } + + + public void run() { + synchronized (this) { + if (!isCancelled()) { + started = true; + } else { + return; + } + } + try { + task.run(); + setSuccess(); + } catch (Throwable t) { + setFailure(t); + } + } + + @Override + public synchronized boolean cancel() { + if (started) { + return false; + } + return super.cancel(); + } + + + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java index a29c876275..30fcc229e9 100644 --- a/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/DatagramChannelConfig.java @@ -15,9 +15,9 @@ */ package org.jboss.netty.channel.socket; +import java.net.DatagramSocket; import java.net.InetAddress; import java.net.NetworkInterface; -import java.net.StandardSocketOptions; import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.FixedReceiveBufferSizePredictor; @@ -49,11 +49,9 @@ import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; * * {@code "receiveBufferSize"}{@link #setReceiveBufferSize(int)} * - * {@code "receiveBufferSizePredictor"} - * {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * {@code "receiveBufferSizePredictor"}{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} * - * {@code "receiveBufferSizePredictorFactory"} - * {@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} + * {@code "receiveBufferSizePredictorFactory"}{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} * * {@code "sendBufferSize"}{@link #setSendBufferSize(int)} * @@ -66,62 +64,64 @@ import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; public interface DatagramChannelConfig extends ChannelConfig { /** - * Gets the {@link StandardSocketOptions#SO_SNDBUF} option. + * Gets the {@code SO_SNDBUF} option. */ int getSendBufferSize(); /** - * Sets the {@link StandardSocketOptions#SO_SNDBUF} option. + * Sets the {@code SO_SNDBUF} option. */ void setSendBufferSize(int sendBufferSize); /** - * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. + * Gets the {@code SO_RCVBUF} option. */ int getReceiveBufferSize(); /** - * Sets the {@link StandardSocketOptions#SO_RCVBUF} option. + * Gets the {@code SO_RCVBUF} option. */ void setReceiveBufferSize(int receiveBufferSize); /** - * Gets the {@link StandardSocketOptions#IP_TOS} option. + * Gets the traffic class. */ int getTrafficClass(); /** - * Gets the {@link StandardSocketOptions#IP_TOS} option. + * Sets the traffic class as specified in {@link DatagramSocket#setTrafficClass(int)}. */ void setTrafficClass(int trafficClass); /** - * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. + * Gets the {@code SO_REUSEADDR} option. */ boolean isReuseAddress(); /** - * Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. + * Sets the {@code SO_REUSEADDR} option. */ void setReuseAddress(boolean reuseAddress); /** - * Gets the {@link StandardSocketOptions#SO_BROADCAST} option. + * Gets the {@code SO_BROADCAST} option. */ boolean isBroadcast(); /** - * Sets the {@link StandardSocketOptions#SO_BROADCAST} option. + * Sets the {@code SO_BROADCAST} option. */ void setBroadcast(boolean broadcast); /** - * Gets the {@link StandardSocketOptions#IP_MULTICAST_LOOP} option. + * Gets the setting for local loopback of multicast datagrams. + * + * @return {@code true} if and only if the loopback mode has been disabled */ boolean isLoopbackModeDisabled(); /** - * Sets the {@link StandardSocketOptions#IP_MULTICAST_LOOP} option. + * Sets the setting for local loopback of multicast datagrams. * * @param loopbackModeDisabled * {@code true} if and only if the loopback mode has been disabled @@ -129,12 +129,14 @@ public interface DatagramChannelConfig extends ChannelConfig { void setLoopbackModeDisabled(boolean loopbackModeDisabled); /** - * Gets the {@link StandardSocketOptions#IP_MULTICAST_TTL} option. + * Gets the default time-to-live for multicast packets sent out on the + * socket. */ int getTimeToLive(); /** - * Sets the {@link StandardSocketOptions#IP_MULTICAST_TTL} option. + * Sets the default time-to-live for multicast packets sent out on the + * {@link DatagramChannel} in order to control the scope of the multicasts. */ void setTimeToLive(int ttl); @@ -149,12 +151,14 @@ public interface DatagramChannelConfig extends ChannelConfig { void setInterface(InetAddress interfaceAddress); /** - * Gets the {@link StandardSocketOptions#IP_MULTICAST_IF} option. + * Gets the network interface for outgoing multicast datagrams sent on + * the {@link DatagramChannel}. */ NetworkInterface getNetworkInterface(); /** - * Sets the {@link StandardSocketOptions#IP_MULTICAST_IF} option. + * Sets the network interface for outgoing multicast datagrams sent on + * the {@link DatagramChannel}. */ void setNetworkInterface(NetworkInterface networkInterface); diff --git a/src/main/java/org/jboss/netty/channel/socket/ServerSocketChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/ServerSocketChannelConfig.java index cdae6dea9a..54a32d5fb4 100644 --- a/src/main/java/org/jboss/netty/channel/socket/ServerSocketChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/ServerSocketChannelConfig.java @@ -16,7 +16,6 @@ package org.jboss.netty.channel.socket; import java.net.ServerSocket; -import java.net.StandardSocketOptions; import org.jboss.netty.channel.ChannelConfig; @@ -56,22 +55,22 @@ public interface ServerSocketChannelConfig extends ChannelConfig { void setBacklog(int backlog); /** - * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. + * Gets the {@code SO_REUSEADDR} option. */ boolean isReuseAddress(); /** - * Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. + * Sets the {@code SO_REUSEADDR} option. */ void setReuseAddress(boolean reuseAddress); /** - * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. + * Gets the {@code SO_RCVBUF} option. */ int getReceiveBufferSize(); /** - * Sets the {@link StandardSocketOptions#SO_RCVBUF} option. + * Sets the {@code SO_RCVBUF} option. */ void setReceiveBufferSize(int receiveBufferSize); diff --git a/src/main/java/org/jboss/netty/channel/socket/SocketChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/SocketChannelConfig.java index 8064c12de0..05498b7f40 100644 --- a/src/main/java/org/jboss/netty/channel/socket/SocketChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/SocketChannelConfig.java @@ -16,7 +16,6 @@ package org.jboss.netty.channel.socket; import java.net.Socket; -import java.net.StandardSocketOptions; import org.jboss.netty.channel.ChannelConfig; @@ -51,72 +50,72 @@ import org.jboss.netty.channel.ChannelConfig; public interface SocketChannelConfig extends ChannelConfig { /** - * Gets the {@link StandardSocketOptions#TCP_NODELAY} option. + * Gets the {@code SO_TCPNODELAY} option. */ boolean isTcpNoDelay(); /** - * Sets the {@link StandardSocketOptions#TCP_NODELAY} option. + * Sets the {@code SO_TCPNODELAY} option. */ void setTcpNoDelay(boolean tcpNoDelay); /** - * Gets the {@link StandardSocketOptions#SO_LINGER} option. + * Gets the {@code SO_LINGER} option. */ int getSoLinger(); /** - * Sets the {@link StandardSocketOptions#SO_LINGER} option. + * Sets the {@code SO_LINGER} option. */ void setSoLinger(int soLinger); /** - * Gets the {@link StandardSocketOptions#SO_SNDBUF} option. + * Gets the {@code SO_SNDBUF} option. */ int getSendBufferSize(); /** - * Sets the {@link StandardSocketOptions#SO_SNDBUF} option. + * Sets the {@code SO_SNDBUF} option. */ void setSendBufferSize(int sendBufferSize); /** - * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. + * Gets the {@code SO_RCVBUF} option. */ int getReceiveBufferSize(); /** - * Sets the {@link StandardSocketOptions#SO_RCVBUF} option. + * Gets the {@code SO_RCVBUF} option. */ void setReceiveBufferSize(int receiveBufferSize); /** - * Gets the {@link StandardSocketOptions#SO_KEEPALIVE} option. + * Gets the {@code SO_KEEPALIVE} option. */ boolean isKeepAlive(); /** - * Sets the {@link StandardSocketOptions#SO_KEEPALIVE} option. + * Sets the {@code SO_KEEPALIVE} option. */ void setKeepAlive(boolean keepAlive); /** - * Gets the {@link StandardSocketOptions#IP_TOS} option. + * Gets the traffic class. */ int getTrafficClass(); /** - * Sets the {@link StandardSocketOptions#IP_TOS} option. + * Sets the traffic class as specified in {@link Socket#setTrafficClass(int)}. */ void setTrafficClass(int trafficClass); /** - * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. + * Gets the {@code SO_REUSEADDR} option. */ boolean isReuseAddress(); /** - * Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. + * Sets the {@code SO_REUSEADDR} option. */ void setReuseAddress(boolean reuseAddress); diff --git a/src/main/java/org/jboss/netty/channel/socket/Worker.java b/src/main/java/org/jboss/netty/channel/socket/Worker.java index 07780d344c..c69c24912a 100644 --- a/src/main/java/org/jboss/netty/channel/socket/Worker.java +++ b/src/main/java/org/jboss/netty/channel/socket/Worker.java @@ -1,33 +1,33 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.jboss.netty.channel.socket; - -/** - * A {@link Worker} is responsible to dispatch IO operations - * - */ -public interface Worker extends Runnable { - - /** - * Execute the given {@link Runnable} in the IO-Thread. This may be now or - * later once the IO-Thread do some other work. - * - * @param task - * the {@link Runnable} to execute - */ - void executeInIoThread(Runnable task); -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package org.jboss.netty.channel.socket; + +/** + * A {@link Worker} is responsible to dispatch IO operations + * + */ +public interface Worker extends Runnable { + + /** + * Execute the given {@link Runnable} in the IO-Thread. This may be now or + * later once the IO-Thread do some other work. + * + * @param task + * the {@link Runnable} to execute + */ + void executeInIoThread(Runnable task); +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannel.java b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannel.java index e88eff5059..31421411c1 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannel.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannel.java @@ -1,370 +1,368 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.nio; - -import static org.jboss.netty.channel.Channels.*; - -import java.net.InetSocketAddress; -import java.nio.channels.SelectableChannel; -import java.nio.channels.WritableByteChannel; -import java.util.Collection; -import java.util.Iterator; -import java.util.Queue; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.AbstractChannel; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFactory; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelSink; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer; -import org.jboss.netty.util.internal.QueueFactory; -import org.jboss.netty.util.internal.ThreadLocalBoolean; - -abstract class AbstractNioChannel extends AbstractChannel { - - /** - * The {@link AbstractNioWorker}. - */ - final AbstractNioWorker worker; - - /** - * Monitor object to synchronize access to InterestedOps. - */ - final Object interestOpsLock = new Object(); - - /** - * Monitor object for synchronizing access to the {@link WriteRequestQueue}. - */ - final Object writeLock = new Object(); - - /** - * WriteTask that performs write operations. - */ - final Runnable writeTask = new WriteTask(); - - /** - * Indicates if there is a {@link WriteTask} in the task queue. - */ - final AtomicBoolean writeTaskInTaskQueue = new AtomicBoolean(); - - /** - * Queue of write {@link MessageEvent}s. - */ - final Queue writeBufferQueue = new WriteRequestQueue(); - - /** - * Keeps track of the number of bytes that the {@link WriteRequestQueue} currently - * contains. - */ - final AtomicInteger writeBufferSize = new AtomicInteger(); - - /** - * Keeps track of the highWaterMark. - */ - final AtomicInteger highWaterMarkCounter = new AtomicInteger(); - - /** - * The current write {@link MessageEvent} - */ - MessageEvent currentWriteEvent; - SendBuffer currentWriteBuffer; - - /** - * Boolean that indicates that write operation is in progress. - */ - boolean inWriteNowLoop; - boolean writeSuspended; - - - private volatile InetSocketAddress localAddress; - volatile InetSocketAddress remoteAddress; - - final C channel; - - protected AbstractNioChannel( - Integer id, Channel parent, ChannelFactory factory, ChannelPipeline pipeline, - ChannelSink sink, AbstractNioWorker worker, C ch) { - super(id, parent, factory, pipeline, sink); - this.worker = worker; - this.channel = ch; - } - - protected AbstractNioChannel( - Channel parent, ChannelFactory factory, - ChannelPipeline pipeline, ChannelSink sink, AbstractNioWorker worker, C ch) { - super(parent, factory, pipeline, sink); - this.worker = worker; - this.channel = ch; - } - - /** - * Return the {@link AbstractNioWorker} that handle the IO of the - * {@link AbstractNioChannel} - * - * @return worker - */ - public AbstractNioWorker getWorker() { - return worker; - } - - public InetSocketAddress getLocalAddress() { - InetSocketAddress localAddress = this.localAddress; - if (localAddress == null) { - try { - this.localAddress = localAddress = getLocalSocketAddress(); - } catch (Throwable t) { - // Sometimes fails on a closed socket in Windows. - return null; - } - } - return localAddress; - } - - public InetSocketAddress getRemoteAddress() { - InetSocketAddress remoteAddress = this.remoteAddress; - if (remoteAddress == null) { - try { - this.remoteAddress = remoteAddress = - getRemoteSocketAddress(); - } catch (Throwable t) { - // Sometimes fails on a closed socket in Windows. - return null; - } - } - return remoteAddress; - } - - public abstract NioChannelConfig getConfig(); - - int getRawInterestOps() { - return super.getInterestOps(); - } - - void setRawInterestOpsNow(int interestOps) { - super.setInterestOpsNow(interestOps); - } - - - @Override - public int getInterestOps() { - if (!isOpen()) { - return Channel.OP_WRITE; - } - - int interestOps = getRawInterestOps(); - int writeBufferSize = this.writeBufferSize.get(); - if (writeBufferSize != 0) { - if (highWaterMarkCounter.get() > 0) { - int lowWaterMark = getConfig().getWriteBufferLowWaterMark(); - if (writeBufferSize >= lowWaterMark) { - interestOps |= Channel.OP_WRITE; - } else { - interestOps &= ~Channel.OP_WRITE; - } - } else { - int highWaterMark = getConfig().getWriteBufferHighWaterMark(); - if (writeBufferSize >= highWaterMark) { - interestOps |= Channel.OP_WRITE; - } else { - interestOps &= ~Channel.OP_WRITE; - } - } - } else { - interestOps &= ~Channel.OP_WRITE; - } - - return interestOps; - } - - @Override - protected boolean setClosed() { - return super.setClosed(); - } - - abstract InetSocketAddress getLocalSocketAddress() throws Exception; - - abstract InetSocketAddress getRemoteSocketAddress() throws Exception; - - private final class WriteRequestQueue implements BlockingQueue { - private final ThreadLocalBoolean notifying = new ThreadLocalBoolean(); - - private final BlockingQueue queue; - - public WriteRequestQueue() { - this.queue = QueueFactory.createQueue(MessageEvent.class); - } - - public MessageEvent remove() { - return queue.remove(); - } - - public MessageEvent element() { - return queue.element(); - } - - public MessageEvent peek() { - return queue.peek(); - } - - public int size() { - return queue.size(); - } - - public boolean isEmpty() { - return queue.isEmpty(); - } - - public Iterator iterator() { - return queue.iterator(); - } - - public Object[] toArray() { - return queue.toArray(); - } - - public T[] toArray(T[] a) { - return queue.toArray(a); - } - - public boolean containsAll(Collection c) { - return queue.containsAll(c); - } - - public boolean addAll(Collection c) { - return queue.addAll(c); - } - - public boolean removeAll(Collection c) { - return queue.removeAll(c); - } - - public boolean retainAll(Collection c) { - return queue.retainAll(c); - } - - public void clear() { - queue.clear(); - } - - public boolean add(MessageEvent e) { - return queue.add(e); - } - - public void put(MessageEvent e) throws InterruptedException { - queue.put(e); - } - - public boolean offer(MessageEvent e, long timeout, TimeUnit unit) throws InterruptedException { - return queue.offer(e, timeout, unit); - } - - public MessageEvent take() throws InterruptedException { - return queue.take(); - } - - public MessageEvent poll(long timeout, TimeUnit unit) throws InterruptedException { - return queue.poll(timeout, unit); - } - - public int remainingCapacity() { - return queue.remainingCapacity(); - } - - public boolean remove(Object o) { - return queue.remove(o); - } - - public boolean contains(Object o) { - return queue.contains(o); - } - - public int drainTo(Collection c) { - return queue.drainTo(c); - } - - public int drainTo(Collection c, int maxElements) { - return queue.drainTo(c, maxElements); - } - - public boolean offer(MessageEvent e) { - boolean success = queue.offer(e); - assert success; - - int messageSize = getMessageSize(e); - int newWriteBufferSize = writeBufferSize.addAndGet(messageSize); - int highWaterMark = getConfig().getWriteBufferHighWaterMark(); - - if (newWriteBufferSize >= highWaterMark) { - if (newWriteBufferSize - messageSize < highWaterMark) { - highWaterMarkCounter.incrementAndGet(); - if (!notifying.get()) { - notifying.set(Boolean.TRUE); - fireChannelInterestChanged(AbstractNioChannel.this); - notifying.set(Boolean.FALSE); - } - } - } - return true; - } - - public MessageEvent poll() { - MessageEvent e = queue.poll(); - if (e != null) { - int messageSize = getMessageSize(e); - int newWriteBufferSize = writeBufferSize.addAndGet(-messageSize); - int lowWaterMark = getConfig().getWriteBufferLowWaterMark(); - - if (newWriteBufferSize == 0 || newWriteBufferSize < lowWaterMark) { - if (newWriteBufferSize + messageSize >= lowWaterMark) { - highWaterMarkCounter.decrementAndGet(); - if (isConnected() && !notifying.get()) { - notifying.set(Boolean.TRUE); - fireChannelInterestChanged(AbstractNioChannel.this); - notifying.set(Boolean.FALSE); - } - } - } - } - return e; - } - - private int getMessageSize(MessageEvent e) { - Object m = e.getMessage(); - if (m instanceof ChannelBuffer) { - return ((ChannelBuffer) m).readableBytes(); - } - return 0; - } - } - - private final class WriteTask implements Runnable { - - WriteTask() { - } - - public void run() { - writeTaskInTaskQueue.set(false); - worker.writeFromTaskLoop(AbstractNioChannel.this); - } - } - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.nio; + +import static org.jboss.netty.channel.Channels.*; + +import java.net.InetSocketAddress; +import java.nio.channels.SelectableChannel; +import java.nio.channels.WritableByteChannel; +import java.util.Collection; +import java.util.Iterator; +import java.util.Queue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.AbstractChannel; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFactory; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelSink; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer; +import org.jboss.netty.util.internal.QueueFactory; +import org.jboss.netty.util.internal.ThreadLocalBoolean; + +abstract class AbstractNioChannel extends AbstractChannel { + + /** + * The {@link AbstractNioWorker}. + */ + final AbstractNioWorker worker; + + /** + * Monitor object to synchronize access to InterestedOps. + */ + final Object interestOpsLock = new Object(); + + /** + * Monitor object for synchronizing access to the {@link WriteRequestQueue}. + */ + final Object writeLock = new Object(); + + /** + * WriteTask that performs write operations. + */ + final Runnable writeTask = new WriteTask(); + + /** + * Indicates if there is a {@link WriteTask} in the task queue. + */ + final AtomicBoolean writeTaskInTaskQueue = new AtomicBoolean(); + + /** + * Queue of write {@link MessageEvent}s. + */ + final Queue writeBufferQueue = new WriteRequestQueue(); + + /** + * Keeps track of the number of bytes that the {@link WriteRequestQueue} currently + * contains. + */ + final AtomicInteger writeBufferSize = new AtomicInteger(); + + /** + * Keeps track of the highWaterMark. + */ + final AtomicInteger highWaterMarkCounter = new AtomicInteger(); + + /** + * The current write {@link MessageEvent} + */ + MessageEvent currentWriteEvent; + SendBuffer currentWriteBuffer; + + /** + * Boolean that indicates that write operation is in progress. + */ + boolean inWriteNowLoop; + boolean writeSuspended; + + + private volatile InetSocketAddress localAddress; + volatile InetSocketAddress remoteAddress; + + final C channel; + + protected AbstractNioChannel(Integer id, Channel parent, ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink, AbstractNioWorker worker, C ch) { + super(id, parent, factory, pipeline, sink); + this.worker = worker; + this.channel = ch; + } + + protected AbstractNioChannel( + Channel parent, ChannelFactory factory, + ChannelPipeline pipeline, ChannelSink sink, AbstractNioWorker worker, C ch) { + super(parent, factory, pipeline, sink); + this.worker = worker; + this.channel = ch; + } + + /** + * Return the {@link AbstractNioWorker} that handle the IO of the + * {@link AbstractNioChannel} + * + * @return worker + */ + public AbstractNioWorker getWorker() { + return worker; + } + + public InetSocketAddress getLocalAddress() { + InetSocketAddress localAddress = this.localAddress; + if (localAddress == null) { + try { + this.localAddress = localAddress = getLocalSocketAddress(); + } catch (Throwable t) { + // Sometimes fails on a closed socket in Windows. + return null; + } + } + return localAddress; + } + + public InetSocketAddress getRemoteAddress() { + InetSocketAddress remoteAddress = this.remoteAddress; + if (remoteAddress == null) { + try { + this.remoteAddress = remoteAddress = + getRemoteSocketAddress(); + } catch (Throwable t) { + // Sometimes fails on a closed socket in Windows. + return null; + } + } + return remoteAddress; + } + + public abstract NioChannelConfig getConfig(); + + int getRawInterestOps() { + return super.getInterestOps(); + } + + void setRawInterestOpsNow(int interestOps) { + super.setInterestOpsNow(interestOps); + } + + + @Override + public int getInterestOps() { + if (!isOpen()) { + return Channel.OP_WRITE; + } + + int interestOps = getRawInterestOps(); + int writeBufferSize = this.writeBufferSize.get(); + if (writeBufferSize != 0) { + if (highWaterMarkCounter.get() > 0) { + int lowWaterMark = getConfig().getWriteBufferLowWaterMark(); + if (writeBufferSize >= lowWaterMark) { + interestOps |= Channel.OP_WRITE; + } else { + interestOps &= ~Channel.OP_WRITE; + } + } else { + int highWaterMark = getConfig().getWriteBufferHighWaterMark(); + if (writeBufferSize >= highWaterMark) { + interestOps |= Channel.OP_WRITE; + } else { + interestOps &= ~Channel.OP_WRITE; + } + } + } else { + interestOps &= ~Channel.OP_WRITE; + } + + return interestOps; + } + + @Override + protected boolean setClosed() { + return super.setClosed(); + } + + abstract InetSocketAddress getLocalSocketAddress() throws Exception; + + abstract InetSocketAddress getRemoteSocketAddress() throws Exception; + + private final class WriteRequestQueue implements BlockingQueue { + private final ThreadLocalBoolean notifying = new ThreadLocalBoolean(); + + private final BlockingQueue queue; + + public WriteRequestQueue() { + this.queue = QueueFactory.createQueue(MessageEvent.class); + } + + public MessageEvent remove() { + return queue.remove(); + } + + public MessageEvent element() { + return queue.element(); + } + + public MessageEvent peek() { + return queue.peek(); + } + + public int size() { + return queue.size(); + } + + public boolean isEmpty() { + return queue.isEmpty(); + } + + public Iterator iterator() { + return queue.iterator(); + } + + public Object[] toArray() { + return queue.toArray(); + } + + public T[] toArray(T[] a) { + return queue.toArray(a); + } + + public boolean containsAll(Collection c) { + return queue.containsAll(c); + } + + public boolean addAll(Collection c) { + return queue.addAll(c); + } + + public boolean removeAll(Collection c) { + return queue.removeAll(c); + } + + public boolean retainAll(Collection c) { + return queue.retainAll(c); + } + + public void clear() { + queue.clear(); + } + + public boolean add(MessageEvent e) { + return queue.add(e); + } + + public void put(MessageEvent e) throws InterruptedException { + queue.put(e); + } + + public boolean offer(MessageEvent e, long timeout, TimeUnit unit) throws InterruptedException { + return queue.offer(e, timeout, unit); + } + + public MessageEvent take() throws InterruptedException { + return queue.take(); + } + + public MessageEvent poll(long timeout, TimeUnit unit) throws InterruptedException { + return queue.poll(timeout, unit); + } + + public int remainingCapacity() { + return queue.remainingCapacity(); + } + + public boolean remove(Object o) { + return queue.remove(o); + } + + public boolean contains(Object o) { + return queue.contains(o); + } + + public int drainTo(Collection c) { + return queue.drainTo(c); + } + + public int drainTo(Collection c, int maxElements) { + return queue.drainTo(c, maxElements); + } + + public boolean offer(MessageEvent e) { + boolean success = queue.offer(e); + assert success; + + int messageSize = getMessageSize(e); + int newWriteBufferSize = writeBufferSize.addAndGet(messageSize); + int highWaterMark = getConfig().getWriteBufferHighWaterMark(); + + if (newWriteBufferSize >= highWaterMark) { + if (newWriteBufferSize - messageSize < highWaterMark) { + highWaterMarkCounter.incrementAndGet(); + if (!notifying.get()) { + notifying.set(Boolean.TRUE); + fireChannelInterestChanged(AbstractNioChannel.this); + notifying.set(Boolean.FALSE); + } + } + } + return true; + } + + public MessageEvent poll() { + MessageEvent e = queue.poll(); + if (e != null) { + int messageSize = getMessageSize(e); + int newWriteBufferSize = writeBufferSize.addAndGet(-messageSize); + int lowWaterMark = getConfig().getWriteBufferLowWaterMark(); + + if (newWriteBufferSize == 0 || newWriteBufferSize < lowWaterMark) { + if (newWriteBufferSize + messageSize >= lowWaterMark) { + highWaterMarkCounter.decrementAndGet(); + if (isConnected() && !notifying.get()) { + notifying.set(Boolean.TRUE); + fireChannelInterestChanged(AbstractNioChannel.this); + notifying.set(Boolean.FALSE); + } + } + } + } + return e; + } + + private int getMessageSize(MessageEvent e) { + Object m = e.getMessage(); + if (m instanceof ChannelBuffer) { + return ((ChannelBuffer) m).readableBytes(); + } + return 0; + } + } + + private final class WriteTask implements Runnable { + + WriteTask() { + } + + public void run() { + writeTaskInTaskQueue.set(false); + worker.writeFromTaskLoop(AbstractNioChannel.this); + } + } + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannelSink.java b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannelSink.java index 13f52a53bf..b54d1f15f5 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannelSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioChannelSink.java @@ -1,52 +1,52 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.jboss.netty.channel.socket.nio; - -import org.jboss.netty.channel.AbstractChannelSink; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelEvent; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.socket.ChannelRunnableWrapper; - -public abstract class AbstractNioChannelSink extends AbstractChannelSink { - - @Override - public ChannelFuture execute(ChannelPipeline pipeline, final Runnable task) { - Channel ch = pipeline.getChannel(); - if (ch instanceof AbstractNioChannel) { - AbstractNioChannel channel = (AbstractNioChannel) ch; - ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task); - channel.worker.executeInIoThread(wrapper); - return wrapper; - } - return super.execute(pipeline, task); - - - } - - @Override - protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) { - Channel channel = event.getChannel(); - boolean fireLater = false; - if (channel instanceof AbstractNioChannel) { - fireLater = !AbstractNioWorker.isIoThread((AbstractNioChannel) channel); - } - return fireLater; - } - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package org.jboss.netty.channel.socket.nio; + +import org.jboss.netty.channel.AbstractChannelSink; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.socket.ChannelRunnableWrapper; + +public abstract class AbstractNioChannelSink extends AbstractChannelSink { + + @Override + public ChannelFuture execute(ChannelPipeline pipeline, final Runnable task) { + Channel ch = pipeline.getChannel(); + if (ch instanceof AbstractNioChannel) { + AbstractNioChannel channel = (AbstractNioChannel) ch; + ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task); + channel.worker.executeInIoThread(wrapper); + return wrapper; + } + return super.execute(pipeline, task); + + + } + + @Override + protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) { + Channel channel = event.getChannel(); + boolean fireLater = false; + if (channel instanceof AbstractNioChannel) { + fireLater = !AbstractNioWorker.isIoThread((AbstractNioChannel) channel); + } + return fireLater; + } + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorker.java b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorker.java index 336677e270..c5e6df1004 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorker.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorker.java @@ -1,825 +1,824 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.nio; - -import static org.jboss.netty.channel.Channels.*; - -import java.io.IOException; -import java.nio.channels.AsynchronousCloseException; -import java.nio.channels.CancelledKeyException; -import java.nio.channels.ClosedChannelException; -import java.nio.channels.NotYetConnectedException; -import java.nio.channels.SelectionKey; -import java.nio.channels.Selector; -import java.nio.channels.WritableByteChannel; -import java.util.Iterator; -import java.util.Queue; -import java.util.Set; -import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelException; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.socket.Worker; -import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer; -import org.jboss.netty.logging.InternalLogger; -import org.jboss.netty.logging.InternalLoggerFactory; -import org.jboss.netty.util.ThreadRenamingRunnable; -import org.jboss.netty.util.internal.DeadLockProofWorker; -import org.jboss.netty.util.internal.QueueFactory; - -abstract class AbstractNioWorker implements Worker { - - - private static final AtomicInteger nextId = new AtomicInteger(); - - final int id = nextId.incrementAndGet(); - - /** - * Internal Netty logger. - */ - private static final InternalLogger logger = InternalLoggerFactory - .getInstance(AbstractNioWorker.class); - - private static final int CONSTRAINT_LEVEL = NioProviderMetadata.CONSTRAINT_LEVEL; - - static final int CLEANUP_INTERVAL = 256; // XXX Hard-coded value, but won't need customization. - - - /** - * Executor used to execute {@link Runnable}s such as channel registration - * task. - */ - private final Executor executor; - - /** - * Boolean to indicate if this worker has been started. - */ - private boolean started; - - /** - * If this worker has been started thread will be a reference to the thread - * used when starting. i.e. the current thread when the run method is executed. - */ - protected volatile Thread thread; - - /** - * The NIO {@link Selector}. - */ - volatile Selector selector; - - /** - * Boolean that controls determines if a blocked Selector.select should - * break out of its selection process. In our case we use a timeone for - * the select method and the select method will block for that time unless - * waken up. - */ - protected final AtomicBoolean wakenUp = new AtomicBoolean(); - - /** - * Lock for this workers Selector. - */ - private final ReadWriteLock selectorGuard = new ReentrantReadWriteLock(); - - /** - * Monitor object used to synchronize selector open/close. - */ - private final Object startStopLock = new Object(); - - /** - * Queue of channel registration tasks. - */ - private final Queue registerTaskQueue = QueueFactory.createQueue(Runnable.class); - - /** - * Queue of WriteTasks - */ - protected final Queue writeTaskQueue = QueueFactory.createQueue(Runnable.class); - - private final Queue eventQueue = QueueFactory.createQueue(Runnable.class); - - - private volatile int cancelledKeys; // should use AtomicInteger but we just need approximation - - protected final SocketSendBufferPool sendBufferPool = new SocketSendBufferPool(); - - private final boolean allowShutdownOnIdle; - - AbstractNioWorker(Executor executor) { - this(executor, true); - } - - public AbstractNioWorker(Executor executor, boolean allowShutdownOnIdle) { - this.executor = executor; - this.allowShutdownOnIdle = allowShutdownOnIdle; - } - - void register(AbstractNioChannel channel, ChannelFuture future) { - - Runnable registerTask = createRegisterTask(channel, future); - Selector selector = start(); - - - boolean offered = registerTaskQueue.offer(registerTask); - assert offered; - - if (wakenUp.compareAndSet(false, true)) { - selector.wakeup(); - } - } - - /** - * Start the {@link AbstractNioWorker} and return the {@link Selector} that will be used for - * the {@link AbstractNioChannel}'s when they get registered - * - * @return selector - */ - private Selector start() { - synchronized (startStopLock) { - if (!started) { - // Open a selector if this worker didn't start yet. - try { - selector = Selector.open(); - } catch (Throwable t) { - throw new ChannelException("Failed to create a selector.", t); - } - - // Start the worker thread with the new Selector. - boolean success = false; - try { - DeadLockProofWorker.start(executor, new ThreadRenamingRunnable(this, "New I/O worker #" + id)); - success = true; - } finally { - if (!success) { - // Release the Selector if the execution fails. - try { - selector.close(); - } catch (Throwable t) { - logger.warn("Failed to close a selector.", t); - } - selector = null; - // The method will return to the caller at this point. - } - } - } - - assert selector != null && selector.isOpen(); - - started = true; - } - return selector; - } - - - public void run() { - thread = Thread.currentThread(); - - boolean shutdown = false; - Selector selector = this.selector; - for (;;) { - wakenUp.set(false); - - if (CONSTRAINT_LEVEL != 0) { - selectorGuard.writeLock().lock(); - // This empty synchronization block prevents the selector - // from acquiring its lock. - selectorGuard.writeLock().unlock(); - } - - try { - SelectorUtil.select(selector); - - // 'wakenUp.compareAndSet(false, true)' is always evaluated - // before calling 'selector.wakeup()' to reduce the wake-up - // overhead. (Selector.wakeup() is an expensive operation.) - // - // However, there is a race condition in this approach. - // The race condition is triggered when 'wakenUp' is set to - // true too early. - // - // 'wakenUp' is set to true too early if: - // 1) Selector is waken up between 'wakenUp.set(false)' and - // 'selector.select(...)'. (BAD) - // 2) Selector is waken up between 'selector.select(...)' and - // 'if (wakenUp.get()) { ... }'. (OK) - // - // In the first case, 'wakenUp' is set to true and the - // following 'selector.select(...)' will wake up immediately. - // Until 'wakenUp' is set to false again in the next round, - // 'wakenUp.compareAndSet(false, true)' will fail, and therefore - // any attempt to wake up the Selector will fail, too, causing - // the following 'selector.select(...)' call to block - // unnecessarily. - // - // To fix this problem, we wake up the selector again if wakenUp - // is true immediately after selector.select(...). - // It is inefficient in that it wakes up the selector for both - // the first case (BAD - wake-up required) and the second case - // (OK - no wake-up required). - - if (wakenUp.get()) { - selector.wakeup(); - } - - cancelledKeys = 0; - processRegisterTaskQueue(); - processEventQueue(); - processWriteTaskQueue(); - processSelectedKeys(selector.selectedKeys()); - - // Exit the loop when there's nothing to handle. - // The shutdown flag is used to delay the shutdown of this - // loop to avoid excessive Selector creation when - // connections are registered in a one-by-one manner instead of - // concurrent manner. - if (selector.keys().isEmpty()) { - if (shutdown || - executor instanceof ExecutorService && ((ExecutorService) executor).isShutdown()) { - - synchronized (startStopLock) { - if (registerTaskQueue.isEmpty() && selector.keys().isEmpty()) { - started = false; - try { - selector.close(); - } catch (IOException e) { - logger.warn( - "Failed to close a selector.", e); - } finally { - this.selector = null; - } - break; - } else { - shutdown = false; - } - } - } else { - if (allowShutdownOnIdle) { - // Give one more second. - shutdown = true; - } - } - } else { - shutdown = false; - } - } catch (Throwable t) { - logger.warn( - "Unexpected exception in the selector loop.", t); - - // Prevent possible consecutive immediate failures that lead to - // excessive CPU consumption. - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - // Ignore. - } - } - } - } - - public void executeInIoThread(Runnable task) { - executeInIoThread(task, false); - } - - /** - * Execute the {@link Runnable} in a IO-Thread - * - * @param task - * the {@link Runnable} to execute - * @param alwaysAsync - * true if the {@link Runnable} should be executed - * in an async fashion even if the current Thread == IO Thread - */ - public void executeInIoThread(Runnable task, boolean alwaysAsync) { - if (!alwaysAsync && Thread.currentThread() == thread) { - task.run(); - } else { - start(); - boolean added = eventQueue.offer(task); - - assert added; - if (added) { - // wake up the selector to speed things - Selector selector = this.selector; - if (selector != null) { - selector.wakeup(); - } - } - } - - } - - - private void processRegisterTaskQueue() throws IOException { - for (;;) { - final Runnable task = registerTaskQueue.poll(); - if (task == null) { - break; - } - - task.run(); - cleanUpCancelledKeys(); - } - } - - private void processWriteTaskQueue() throws IOException { - for (;;) { - final Runnable task = writeTaskQueue.poll(); - if (task == null) { - break; - } - - task.run(); - cleanUpCancelledKeys(); - } - } - - private void processEventQueue() throws IOException { - for (;;) { - final Runnable task = eventQueue.poll(); - if (task == null) { - break; - } - task.run(); - cleanUpCancelledKeys(); - } - } - - private void processSelectedKeys(Set selectedKeys) throws IOException { - for (Iterator i = selectedKeys.iterator(); i.hasNext();) { - SelectionKey k = i.next(); - i.remove(); - try { - int readyOps = k.readyOps(); - if ((readyOps & SelectionKey.OP_READ) != 0 || readyOps == 0) { - if (!read(k)) { - // Connection already closed - no need to handle write. - continue; - } - } - if ((readyOps & SelectionKey.OP_WRITE) != 0) { - writeFromSelectorLoop(k); - } - } catch (CancelledKeyException e) { - close(k); - } - - if (cleanUpCancelledKeys()) { - break; // break the loop to avoid ConcurrentModificationException - } - } - } - - private boolean cleanUpCancelledKeys() throws IOException { - if (cancelledKeys >= CLEANUP_INTERVAL) { - cancelledKeys = 0; - selector.selectNow(); - return true; - } - return false; - } - - - - private void close(SelectionKey k) { - AbstractNioChannel ch = (AbstractNioChannel) k.attachment(); - close(ch, succeededFuture(ch)); - } - - void writeFromUserCode(final AbstractNioChannel channel) { - if (!channel.isConnected()) { - cleanUpWriteBuffer(channel); - return; - } - - if (scheduleWriteIfNecessary(channel)) { - return; - } - - // From here, we are sure Thread.currentThread() == workerThread. - - if (channel.writeSuspended) { - return; - } - - if (channel.inWriteNowLoop) { - return; - } - - write0(channel); - } - - void writeFromTaskLoop(AbstractNioChannel ch) { - if (!ch.writeSuspended) { - write0(ch); - } - } - - void writeFromSelectorLoop(final SelectionKey k) { - AbstractNioChannel ch = (AbstractNioChannel) k.attachment(); - ch.writeSuspended = false; - write0(ch); - } - - protected abstract boolean scheduleWriteIfNecessary(final AbstractNioChannel channel); - - protected void write0(AbstractNioChannel channel) { - boolean open = true; - boolean addOpWrite = false; - boolean removeOpWrite = false; - boolean iothread = isIoThread(channel); - - long writtenBytes = 0; - - final SocketSendBufferPool sendBufferPool = this.sendBufferPool; - final WritableByteChannel ch = channel.channel; - final Queue writeBuffer = channel.writeBufferQueue; - final int writeSpinCount = channel.getConfig().getWriteSpinCount(); - synchronized (channel.writeLock) { - channel.inWriteNowLoop = true; - for (;;) { - MessageEvent evt = channel.currentWriteEvent; - SendBuffer buf; - if (evt == null) { - if ((channel.currentWriteEvent = evt = writeBuffer.poll()) == null) { - removeOpWrite = true; - channel.writeSuspended = false; - break; - } - - channel.currentWriteBuffer = buf = sendBufferPool.acquire(evt.getMessage()); - } else { - buf = channel.currentWriteBuffer; - } - - ChannelFuture future = evt.getFuture(); - try { - long localWrittenBytes = 0; - for (int i = writeSpinCount; i > 0; i --) { - localWrittenBytes = buf.transferTo(ch); - if (localWrittenBytes != 0) { - writtenBytes += localWrittenBytes; - break; - } - if (buf.finished()) { - break; - } - } - - if (buf.finished()) { - // Successful write - proceed to the next message. - buf.release(); - channel.currentWriteEvent = null; - channel.currentWriteBuffer = null; - evt = null; - buf = null; - future.setSuccess(); - } else { - // Not written fully - perhaps the kernel buffer is full. - addOpWrite = true; - channel.writeSuspended = true; - - if (localWrittenBytes > 0) { - // Notify progress listeners if necessary. - future.setProgress( - localWrittenBytes, - buf.writtenBytes(), buf.totalBytes()); - } - break; - } - } catch (AsynchronousCloseException e) { - // Doesn't need a user attention - ignore. - } catch (Throwable t) { - if (buf != null) { - buf.release(); - } - channel.currentWriteEvent = null; - channel.currentWriteBuffer = null; - buf = null; - evt = null; - future.setFailure(t); - if (iothread) { - fireExceptionCaught(channel, t); - } else { - fireExceptionCaughtLater(channel, t); - } - if (t instanceof IOException) { - open = false; - close(channel, succeededFuture(channel)); - } - } - } - channel.inWriteNowLoop = false; - - // Initially, the following block was executed after releasing - // the writeLock, but there was a race condition, and it has to be - // executed before releasing the writeLock: - // - // https://issues.jboss.org/browse/NETTY-410 - // - if (open) { - if (addOpWrite) { - setOpWrite(channel); - } else if (removeOpWrite) { - clearOpWrite(channel); - } - } - } - if (iothread) { - fireWriteComplete(channel, writtenBytes); - } else { - fireWriteCompleteLater(channel, writtenBytes); - } - } - - static boolean isIoThread(AbstractNioChannel channel) { - return Thread.currentThread() == channel.worker.thread; - } - - protected void setOpWrite(AbstractNioChannel channel) { - Selector selector = this.selector; - SelectionKey key = channel.channel.keyFor(selector); - if (key == null) { - return; - } - if (!key.isValid()) { - close(key); - return; - } - - // interestOps can change at any time and at any thread. - // Acquire a lock to avoid possible race condition. - synchronized (channel.interestOpsLock) { - int interestOps = channel.getRawInterestOps(); - if ((interestOps & SelectionKey.OP_WRITE) == 0) { - interestOps |= SelectionKey.OP_WRITE; - key.interestOps(interestOps); - channel.setRawInterestOpsNow(interestOps); - } - } - } - - protected void clearOpWrite(AbstractNioChannel channel) { - Selector selector = this.selector; - SelectionKey key = channel.channel.keyFor(selector); - if (key == null) { - return; - } - if (!key.isValid()) { - close(key); - return; - } - - // interestOps can change at any time and at any thread. - // Acquire a lock to avoid possible race condition. - synchronized (channel.interestOpsLock) { - int interestOps = channel.getRawInterestOps(); - if ((interestOps & SelectionKey.OP_WRITE) != 0) { - interestOps &= ~SelectionKey.OP_WRITE; - key.interestOps(interestOps); - channel.setRawInterestOpsNow(interestOps); - } - } - } - - - void close(AbstractNioChannel channel, ChannelFuture future) { - boolean connected = channel.isConnected(); - boolean bound = channel.isBound(); - boolean iothread = isIoThread(channel); - - try { - channel.channel.close(); - cancelledKeys ++; - - if (channel.setClosed()) { - future.setSuccess(); - if (connected) { - if (iothread) { - fireChannelDisconnected(channel); - } else { - fireChannelDisconnectedLater(channel); - } - } - if (bound) { - if (iothread) { - fireChannelUnbound(channel); - } else { - fireChannelUnboundLater(channel); - } - } - - cleanUpWriteBuffer(channel); - if (iothread) { - fireChannelClosed(channel); - } else { - fireChannelClosedLater(channel); - } - } else { - future.setSuccess(); - } - } catch (Throwable t) { - future.setFailure(t); - if (iothread) { - fireExceptionCaught(channel, t); - } else { - fireExceptionCaughtLater(channel, t); - } - } - } - - protected void cleanUpWriteBuffer(AbstractNioChannel channel) { - Exception cause = null; - boolean fireExceptionCaught = false; - - // Clean up the stale messages in the write buffer. - synchronized (channel.writeLock) { - MessageEvent evt = channel.currentWriteEvent; - if (evt != null) { - // Create the exception only once to avoid the excessive overhead - // caused by fillStackTrace. - if (channel.isOpen()) { - cause = new NotYetConnectedException(); - } else { - cause = new ClosedChannelException(); - } - - ChannelFuture future = evt.getFuture(); - channel.currentWriteBuffer.release(); - channel.currentWriteBuffer = null; - channel.currentWriteEvent = null; - evt = null; - future.setFailure(cause); - fireExceptionCaught = true; - } - - Queue writeBuffer = channel.writeBufferQueue; - for (;;) { - evt = writeBuffer.poll(); - if (evt == null) { - break; - } - // Create the exception only once to avoid the excessive overhead - // caused by fillStackTrace. - if (cause == null) { - if (channel.isOpen()) { - cause = new NotYetConnectedException(); - } else { - cause = new ClosedChannelException(); - } - fireExceptionCaught = true; - } - evt.getFuture().setFailure(cause); - - - } - } - - if (fireExceptionCaught) { - if (isIoThread(channel)) { - fireExceptionCaught(channel, cause); - } else { - fireExceptionCaughtLater(channel, cause); - } - } - } - - void setInterestOps(AbstractNioChannel channel, ChannelFuture future, int interestOps) { - boolean changed = false; - boolean iothread = isIoThread(channel); - try { - // interestOps can change at any time and at any thread. - // Acquire a lock to avoid possible race condition. - synchronized (channel.interestOpsLock) { - Selector selector = this.selector; - SelectionKey key = channel.channel.keyFor(selector); - - // Override OP_WRITE flag - a user cannot change this flag. - interestOps &= ~Channel.OP_WRITE; - interestOps |= channel.getRawInterestOps() & Channel.OP_WRITE; - - if (key == null || selector == null) { - if (channel.getRawInterestOps() != interestOps) { - changed = true; - } - - // Not registered to the worker yet. - // Set the rawInterestOps immediately; RegisterTask will pick it up. - channel.setRawInterestOpsNow(interestOps); - - future.setSuccess(); - if (changed) { - if (iothread) { - fireChannelInterestChanged(channel); - } else { - fireChannelInterestChangedLater(channel); - } - } - - return; - } - - switch (CONSTRAINT_LEVEL) { - case 0: - if (channel.getRawInterestOps() != interestOps) { - key.interestOps(interestOps); - if (Thread.currentThread() != thread && - wakenUp.compareAndSet(false, true)) { - selector.wakeup(); - } - changed = true; - } - break; - case 1: - case 2: - if (channel.getRawInterestOps() != interestOps) { - if (Thread.currentThread() == thread) { - key.interestOps(interestOps); - changed = true; - } else { - selectorGuard.readLock().lock(); - try { - if (wakenUp.compareAndSet(false, true)) { - selector.wakeup(); - } - key.interestOps(interestOps); - changed = true; - } finally { - selectorGuard.readLock().unlock(); - } - } - } - break; - default: - throw new Error(); - } - - if (changed) { - channel.setRawInterestOpsNow(interestOps); - } - } - - future.setSuccess(); - if (changed) { - if (iothread) { - fireChannelInterestChanged(channel); - } else { - fireChannelInterestChangedLater(channel); - } - } - } catch (CancelledKeyException e) { - // setInterestOps() was called on a closed channel. - ClosedChannelException cce = new ClosedChannelException(); - future.setFailure(cce); - if (iothread) { - fireExceptionCaught(channel, cce); - } else { - fireExceptionCaughtLater(channel, cce); - } - } catch (Throwable t) { - future.setFailure(t); - if (iothread) { - fireExceptionCaught(channel, t); - } else { - fireExceptionCaughtLater(channel, t); - } - } - } - - /** - * Read is called when a Selector has been notified that the underlying channel - * was something to be read. The channel would previously have registered its interest - * in read operations. - * - * @param k The selection key which contains the Selector registration information. - */ - protected abstract boolean read(SelectionKey k); - - /** - * Create a new {@link Runnable} which will register the {@link AbstractNioWorker} with the {@link Channel} - * - * @param channel - * @param future - * @return task - */ - protected abstract Runnable createRegisterTask(AbstractNioChannel channel, ChannelFuture future); - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.nio; + +import static org.jboss.netty.channel.Channels.*; + +import java.io.IOException; +import java.nio.channels.AsynchronousCloseException; +import java.nio.channels.CancelledKeyException; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.NotYetConnectedException; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.nio.channels.WritableByteChannel; +import java.util.Iterator; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelException; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.socket.Worker; +import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer; +import org.jboss.netty.logging.InternalLogger; +import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.util.ThreadRenamingRunnable; +import org.jboss.netty.util.internal.DeadLockProofWorker; +import org.jboss.netty.util.internal.QueueFactory; + +abstract class AbstractNioWorker implements Worker { + + + private static final AtomicInteger nextId = new AtomicInteger(); + + final int id = nextId.incrementAndGet(); + + /** + * Internal Netty logger. + */ + private static final InternalLogger logger = InternalLoggerFactory + .getInstance(AbstractNioWorker.class); + + private static final int CONSTRAINT_LEVEL = NioProviderMetadata.CONSTRAINT_LEVEL; + + static final int CLEANUP_INTERVAL = 256; // XXX Hard-coded value, but won't need customization. + + + /** + * Executor used to execute {@link Runnable}s such as channel registration + * task. + */ + private final Executor executor; + + /** + * Boolean to indicate if this worker has been started. + */ + private boolean started; + + /** + * If this worker has been started thread will be a reference to the thread + * used when starting. i.e. the current thread when the run method is executed. + */ + protected volatile Thread thread; + + /** + * The NIO {@link Selector}. + */ + volatile Selector selector; + + /** + * Boolean that controls determines if a blocked Selector.select should + * break out of its selection process. In our case we use a timeone for + * the select method and the select method will block for that time unless + * waken up. + */ + protected final AtomicBoolean wakenUp = new AtomicBoolean(); + + /** + * Lock for this workers Selector. + */ + private final ReadWriteLock selectorGuard = new ReentrantReadWriteLock(); + + /** + * Monitor object used to synchronize selector open/close. + */ + private final Object startStopLock = new Object(); + + /** + * Queue of channel registration tasks. + */ + private final Queue registerTaskQueue = QueueFactory.createQueue(Runnable.class); + + /** + * Queue of WriteTasks + */ + protected final Queue writeTaskQueue = QueueFactory.createQueue(Runnable.class); + + private final Queue eventQueue = QueueFactory.createQueue(Runnable.class); + + + private volatile int cancelledKeys; // should use AtomicInteger but we just need approximation + + protected final SocketSendBufferPool sendBufferPool = new SocketSendBufferPool(); + + private final boolean allowShutdownOnIdle; + + AbstractNioWorker(Executor executor) { + this(executor, true); + } + + public AbstractNioWorker(Executor executor, boolean allowShutdownOnIdle) { + this.executor = executor; + this.allowShutdownOnIdle = allowShutdownOnIdle; + } + + void register(AbstractNioChannel channel, ChannelFuture future) { + + Runnable registerTask = createRegisterTask(channel, future); + Selector selector = start(); + + + boolean offered = registerTaskQueue.offer(registerTask); + assert offered; + + if (wakenUp.compareAndSet(false, true)) { + selector.wakeup(); + } + } + + /** + * Start the {@link AbstractNioWorker} and return the {@link Selector} that will be used for the {@link AbstractNioChannel}'s when they get registered + * + * @return selector + */ + private Selector start() { + synchronized (startStopLock) { + if (!started) { + // Open a selector if this worker didn't start yet. + try { + selector = Selector.open(); + } catch (Throwable t) { + throw new ChannelException("Failed to create a selector.", t); + } + + // Start the worker thread with the new Selector. + boolean success = false; + try { + DeadLockProofWorker.start(executor, new ThreadRenamingRunnable(this, "New I/O worker #" + id)); + success = true; + } finally { + if (!success) { + // Release the Selector if the execution fails. + try { + selector.close(); + } catch (Throwable t) { + logger.warn("Failed to close a selector.", t); + } + selector = null; + // The method will return to the caller at this point. + } + } + } + + assert selector != null && selector.isOpen(); + + started = true; + } + return selector; + } + + + public void run() { + thread = Thread.currentThread(); + + boolean shutdown = false; + Selector selector = this.selector; + for (;;) { + wakenUp.set(false); + + if (CONSTRAINT_LEVEL != 0) { + selectorGuard.writeLock().lock(); + // This empty synchronization block prevents the selector + // from acquiring its lock. + selectorGuard.writeLock().unlock(); + } + + try { + SelectorUtil.select(selector); + + // 'wakenUp.compareAndSet(false, true)' is always evaluated + // before calling 'selector.wakeup()' to reduce the wake-up + // overhead. (Selector.wakeup() is an expensive operation.) + // + // However, there is a race condition in this approach. + // The race condition is triggered when 'wakenUp' is set to + // true too early. + // + // 'wakenUp' is set to true too early if: + // 1) Selector is waken up between 'wakenUp.set(false)' and + // 'selector.select(...)'. (BAD) + // 2) Selector is waken up between 'selector.select(...)' and + // 'if (wakenUp.get()) { ... }'. (OK) + // + // In the first case, 'wakenUp' is set to true and the + // following 'selector.select(...)' will wake up immediately. + // Until 'wakenUp' is set to false again in the next round, + // 'wakenUp.compareAndSet(false, true)' will fail, and therefore + // any attempt to wake up the Selector will fail, too, causing + // the following 'selector.select(...)' call to block + // unnecessarily. + // + // To fix this problem, we wake up the selector again if wakenUp + // is true immediately after selector.select(...). + // It is inefficient in that it wakes up the selector for both + // the first case (BAD - wake-up required) and the second case + // (OK - no wake-up required). + + if (wakenUp.get()) { + selector.wakeup(); + } + + cancelledKeys = 0; + processRegisterTaskQueue(); + processEventQueue(); + processWriteTaskQueue(); + processSelectedKeys(selector.selectedKeys()); + + // Exit the loop when there's nothing to handle. + // The shutdown flag is used to delay the shutdown of this + // loop to avoid excessive Selector creation when + // connections are registered in a one-by-one manner instead of + // concurrent manner. + if (selector.keys().isEmpty()) { + if (shutdown || + executor instanceof ExecutorService && ((ExecutorService) executor).isShutdown()) { + + synchronized (startStopLock) { + if (registerTaskQueue.isEmpty() && selector.keys().isEmpty()) { + started = false; + try { + selector.close(); + } catch (IOException e) { + logger.warn( + "Failed to close a selector.", e); + } finally { + this.selector = null; + } + break; + } else { + shutdown = false; + } + } + } else { + if (allowShutdownOnIdle) { + // Give one more second. + shutdown = true; + } + } + } else { + shutdown = false; + } + } catch (Throwable t) { + logger.warn( + "Unexpected exception in the selector loop.", t); + + // Prevent possible consecutive immediate failures that lead to + // excessive CPU consumption. + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // Ignore. + } + } + } + } + + public void executeInIoThread(Runnable task) { + executeInIoThread(task, false); + } + + /** + * Execute the {@link Runnable} in a IO-Thread + * + * @param task + * the {@link Runnable} to execute + * @param alwaysAsync + * true if the {@link Runnable} should be executed + * in an async fashion even if the current Thread == IO Thread + */ + public void executeInIoThread(Runnable task, boolean alwaysAsync) { + if (!alwaysAsync && Thread.currentThread() == thread) { + task.run(); + } else { + start(); + boolean added = eventQueue.offer(task); + + assert added; + if (added) { + // wake up the selector to speed things + Selector selector = this.selector; + if (selector != null) { + selector.wakeup(); + } + } + } + + } + + + private void processRegisterTaskQueue() throws IOException { + for (;;) { + final Runnable task = registerTaskQueue.poll(); + if (task == null) { + break; + } + + task.run(); + cleanUpCancelledKeys(); + } + } + + private void processWriteTaskQueue() throws IOException { + for (;;) { + final Runnable task = writeTaskQueue.poll(); + if (task == null) { + break; + } + + task.run(); + cleanUpCancelledKeys(); + } + } + + private void processEventQueue() throws IOException { + for (;;) { + final Runnable task = eventQueue.poll(); + if (task == null) { + break; + } + task.run(); + cleanUpCancelledKeys(); + } + } + + private void processSelectedKeys(Set selectedKeys) throws IOException { + for (Iterator i = selectedKeys.iterator(); i.hasNext();) { + SelectionKey k = i.next(); + i.remove(); + try { + int readyOps = k.readyOps(); + if ((readyOps & SelectionKey.OP_READ) != 0 || readyOps == 0) { + if (!read(k)) { + // Connection already closed - no need to handle write. + continue; + } + } + if ((readyOps & SelectionKey.OP_WRITE) != 0) { + writeFromSelectorLoop(k); + } + } catch (CancelledKeyException e) { + close(k); + } + + if (cleanUpCancelledKeys()) { + break; // break the loop to avoid ConcurrentModificationException + } + } + } + + private boolean cleanUpCancelledKeys() throws IOException { + if (cancelledKeys >= CLEANUP_INTERVAL) { + cancelledKeys = 0; + selector.selectNow(); + return true; + } + return false; + } + + + + private void close(SelectionKey k) { + AbstractNioChannel ch = (AbstractNioChannel) k.attachment(); + close(ch, succeededFuture(ch)); + } + + void writeFromUserCode(final AbstractNioChannel channel) { + if (!channel.isConnected()) { + cleanUpWriteBuffer(channel); + return; + } + + if (scheduleWriteIfNecessary(channel)) { + return; + } + + // From here, we are sure Thread.currentThread() == workerThread. + + if (channel.writeSuspended) { + return; + } + + if (channel.inWriteNowLoop) { + return; + } + + write0(channel); + } + + void writeFromTaskLoop(AbstractNioChannel ch) { + if (!ch.writeSuspended) { + write0(ch); + } + } + + void writeFromSelectorLoop(final SelectionKey k) { + AbstractNioChannel ch = (AbstractNioChannel) k.attachment(); + ch.writeSuspended = false; + write0(ch); + } + + protected abstract boolean scheduleWriteIfNecessary(final AbstractNioChannel channel); + + protected void write0(AbstractNioChannel channel) { + boolean open = true; + boolean addOpWrite = false; + boolean removeOpWrite = false; + boolean iothread = isIoThread(channel); + + long writtenBytes = 0; + + final SocketSendBufferPool sendBufferPool = this.sendBufferPool; + final WritableByteChannel ch = channel.channel; + final Queue writeBuffer = channel.writeBufferQueue; + final int writeSpinCount = channel.getConfig().getWriteSpinCount(); + synchronized (channel.writeLock) { + channel.inWriteNowLoop = true; + for (;;) { + MessageEvent evt = channel.currentWriteEvent; + SendBuffer buf; + if (evt == null) { + if ((channel.currentWriteEvent = evt = writeBuffer.poll()) == null) { + removeOpWrite = true; + channel.writeSuspended = false; + break; + } + + channel.currentWriteBuffer = buf = sendBufferPool.acquire(evt.getMessage()); + } else { + buf = channel.currentWriteBuffer; + } + + ChannelFuture future = evt.getFuture(); + try { + long localWrittenBytes = 0; + for (int i = writeSpinCount; i > 0; i --) { + localWrittenBytes = buf.transferTo(ch); + if (localWrittenBytes != 0) { + writtenBytes += localWrittenBytes; + break; + } + if (buf.finished()) { + break; + } + } + + if (buf.finished()) { + // Successful write - proceed to the next message. + buf.release(); + channel.currentWriteEvent = null; + channel.currentWriteBuffer = null; + evt = null; + buf = null; + future.setSuccess(); + } else { + // Not written fully - perhaps the kernel buffer is full. + addOpWrite = true; + channel.writeSuspended = true; + + if (localWrittenBytes > 0) { + // Notify progress listeners if necessary. + future.setProgress( + localWrittenBytes, + buf.writtenBytes(), buf.totalBytes()); + } + break; + } + } catch (AsynchronousCloseException e) { + // Doesn't need a user attention - ignore. + } catch (Throwable t) { + if (buf != null) { + buf.release(); + } + channel.currentWriteEvent = null; + channel.currentWriteBuffer = null; + buf = null; + evt = null; + future.setFailure(t); + if (iothread) { + fireExceptionCaught(channel, t); + } else { + fireExceptionCaughtLater(channel, t); + } + if (t instanceof IOException) { + open = false; + close(channel, succeededFuture(channel)); + } + } + } + channel.inWriteNowLoop = false; + + // Initially, the following block was executed after releasing + // the writeLock, but there was a race condition, and it has to be + // executed before releasing the writeLock: + // + // https://issues.jboss.org/browse/NETTY-410 + // + if (open) { + if (addOpWrite) { + setOpWrite(channel); + } else if (removeOpWrite) { + clearOpWrite(channel); + } + } + } + if (iothread) { + fireWriteComplete(channel, writtenBytes); + } else { + fireWriteCompleteLater(channel, writtenBytes); + } + } + + static boolean isIoThread(AbstractNioChannel channel) { + return Thread.currentThread() == channel.worker.thread; + } + + protected void setOpWrite(AbstractNioChannel channel) { + Selector selector = this.selector; + SelectionKey key = channel.channel.keyFor(selector); + if (key == null) { + return; + } + if (!key.isValid()) { + close(key); + return; + } + + // interestOps can change at any time and at any thread. + // Acquire a lock to avoid possible race condition. + synchronized (channel.interestOpsLock) { + int interestOps = channel.getRawInterestOps(); + if ((interestOps & SelectionKey.OP_WRITE) == 0) { + interestOps |= SelectionKey.OP_WRITE; + key.interestOps(interestOps); + channel.setRawInterestOpsNow(interestOps); + } + } + } + + protected void clearOpWrite(AbstractNioChannel channel) { + Selector selector = this.selector; + SelectionKey key = channel.channel.keyFor(selector); + if (key == null) { + return; + } + if (!key.isValid()) { + close(key); + return; + } + + // interestOps can change at any time and at any thread. + // Acquire a lock to avoid possible race condition. + synchronized (channel.interestOpsLock) { + int interestOps = channel.getRawInterestOps(); + if ((interestOps & SelectionKey.OP_WRITE) != 0) { + interestOps &= ~SelectionKey.OP_WRITE; + key.interestOps(interestOps); + channel.setRawInterestOpsNow(interestOps); + } + } + } + + + void close(AbstractNioChannel channel, ChannelFuture future) { + boolean connected = channel.isConnected(); + boolean bound = channel.isBound(); + boolean iothread = isIoThread(channel); + + try { + channel.channel.close(); + cancelledKeys ++; + + if (channel.setClosed()) { + future.setSuccess(); + if (connected) { + if (iothread) { + fireChannelDisconnected(channel); + } else { + fireChannelDisconnectedLater(channel); + } + } + if (bound) { + if (iothread) { + fireChannelUnbound(channel); + } else { + fireChannelUnboundLater(channel); + } + } + + cleanUpWriteBuffer(channel); + if (iothread) { + fireChannelClosed(channel); + } else { + fireChannelClosedLater(channel); + } + } else { + future.setSuccess(); + } + } catch (Throwable t) { + future.setFailure(t); + if (iothread) { + fireExceptionCaught(channel, t); + } else { + fireExceptionCaughtLater(channel, t); + } + } + } + + protected void cleanUpWriteBuffer(AbstractNioChannel channel) { + Exception cause = null; + boolean fireExceptionCaught = false; + + // Clean up the stale messages in the write buffer. + synchronized (channel.writeLock) { + MessageEvent evt = channel.currentWriteEvent; + if (evt != null) { + // Create the exception only once to avoid the excessive overhead + // caused by fillStackTrace. + if (channel.isOpen()) { + cause = new NotYetConnectedException(); + } else { + cause = new ClosedChannelException(); + } + + ChannelFuture future = evt.getFuture(); + channel.currentWriteBuffer.release(); + channel.currentWriteBuffer = null; + channel.currentWriteEvent = null; + evt = null; + future.setFailure(cause); + fireExceptionCaught = true; + } + + Queue writeBuffer = channel.writeBufferQueue; + for (;;) { + evt = writeBuffer.poll(); + if (evt == null) { + break; + } + // Create the exception only once to avoid the excessive overhead + // caused by fillStackTrace. + if (cause == null) { + if (channel.isOpen()) { + cause = new NotYetConnectedException(); + } else { + cause = new ClosedChannelException(); + } + fireExceptionCaught = true; + } + evt.getFuture().setFailure(cause); + + + } + } + + if (fireExceptionCaught) { + if (isIoThread(channel)) { + fireExceptionCaught(channel, cause); + } else { + fireExceptionCaughtLater(channel, cause); + } + } + } + + void setInterestOps(AbstractNioChannel channel, ChannelFuture future, int interestOps) { + boolean changed = false; + boolean iothread = isIoThread(channel); + try { + // interestOps can change at any time and at any thread. + // Acquire a lock to avoid possible race condition. + synchronized (channel.interestOpsLock) { + Selector selector = this.selector; + SelectionKey key = channel.channel.keyFor(selector); + + // Override OP_WRITE flag - a user cannot change this flag. + interestOps &= ~Channel.OP_WRITE; + interestOps |= channel.getRawInterestOps() & Channel.OP_WRITE; + + if (key == null || selector == null) { + if (channel.getRawInterestOps() != interestOps) { + changed = true; + } + + // Not registered to the worker yet. + // Set the rawInterestOps immediately; RegisterTask will pick it up. + channel.setRawInterestOpsNow(interestOps); + + future.setSuccess(); + if (changed) { + if (iothread) { + fireChannelInterestChanged(channel); + } else { + fireChannelInterestChangedLater(channel); + } + } + + return; + } + + switch (CONSTRAINT_LEVEL) { + case 0: + if (channel.getRawInterestOps() != interestOps) { + key.interestOps(interestOps); + if (Thread.currentThread() != thread && + wakenUp.compareAndSet(false, true)) { + selector.wakeup(); + } + changed = true; + } + break; + case 1: + case 2: + if (channel.getRawInterestOps() != interestOps) { + if (Thread.currentThread() == thread) { + key.interestOps(interestOps); + changed = true; + } else { + selectorGuard.readLock().lock(); + try { + if (wakenUp.compareAndSet(false, true)) { + selector.wakeup(); + } + key.interestOps(interestOps); + changed = true; + } finally { + selectorGuard.readLock().unlock(); + } + } + } + break; + default: + throw new Error(); + } + + if (changed) { + channel.setRawInterestOpsNow(interestOps); + } + } + + future.setSuccess(); + if (changed) { + if (iothread) { + fireChannelInterestChanged(channel); + } else { + fireChannelInterestChangedLater(channel); + } + } + } catch (CancelledKeyException e) { + // setInterestOps() was called on a closed channel. + ClosedChannelException cce = new ClosedChannelException(); + future.setFailure(cce); + if (iothread) { + fireExceptionCaught(channel, cce); + } else { + fireExceptionCaughtLater(channel, cce); + } + } catch (Throwable t) { + future.setFailure(t); + if (iothread) { + fireExceptionCaught(channel, t); + } else { + fireExceptionCaughtLater(channel, t); + } + } + } + + /** + * Read is called when a Selector has been notified that the underlying channel + * was something to be read. The channel would previously have registered its interest + * in read operations. + * + * @param k The selection key which contains the Selector registration information. + */ + protected abstract boolean read(SelectionKey k); + + /** + * Create a new {@link Runnable} which will register the {@link AbstractNioWorker} with the {@link Channel} + * + * @param channel + * @param future + * @return task + */ + protected abstract Runnable createRegisterTask(AbstractNioChannel channel, ChannelFuture future); + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorkerPool.java b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorkerPool.java index 8723ebd1df..b3400c9832 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorkerPool.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/AbstractNioWorkerPool.java @@ -1,85 +1,83 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.jboss.netty.channel.socket.nio; - -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicInteger; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.socket.Worker; -import org.jboss.netty.util.ExternalResourceReleasable; -import org.jboss.netty.util.internal.ExecutorUtil; - -/** - * Abstract base class for {@link WorkerPool} implementations that create the {@link Worker}'s - * up-front and return them in a "fair" fashion when calling {@link #nextWorker()} - */ -public abstract class AbstractNioWorkerPool - implements WorkerPool, ExternalResourceReleasable { - - private final AbstractNioWorker[] workers; - private final AtomicInteger workerIndex = new AtomicInteger(); - private final Executor workerExecutor; - - /** - * Create a new instance - * - * @param workerExecutor the {@link Executor} to use for the {@link Worker}'s - * @param allowShutdownOnIdle allow the {@link Worker}'s to shutdown when there is not - * {@link Channel} is registered with it - * @param workerCount the count of {@link Worker}'s to create - */ - AbstractNioWorkerPool(Executor workerExecutor, int workerCount, boolean allowShutDownOnIdle) { - if (workerExecutor == null) { - throw new NullPointerException("workerExecutor"); - } - if (workerCount <= 0) { - throw new IllegalArgumentException( - "workerCount (" + workerCount + ") " + - "must be a positive integer."); - } - workers = new AbstractNioWorker[workerCount]; - - for (int i = 0; i < workers.length; i++) { - workers[i] = createWorker(workerExecutor, allowShutDownOnIdle); - } - this.workerExecutor = workerExecutor; - - } - - /** - * Create a new {@link Worker} which uses the given {@link Executor} to service IO - * - * - * @param executor the {@link Executor} to use - * @param allowShutdownOnIdle allow the {@link Worker} to shutdown when there is not - * {@link Channel} is registered with it - * @return worker the new {@link Worker} - */ - protected abstract E createWorker(Executor executor, boolean allowShutdownOnIdle); - - @SuppressWarnings("unchecked") - public E nextWorker() { - return (E) workers[Math.abs(workerIndex.getAndIncrement() % workers.length)]; - } - - - public void releaseExternalResources() { - ExecutorUtil.terminate(workerExecutor); - } - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package org.jboss.netty.channel.socket.nio; + +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.socket.Worker; +import org.jboss.netty.util.ExternalResourceReleasable; +import org.jboss.netty.util.internal.ExecutorUtil; + +/** + * Abstract base class for {@link WorkerPool} implementations that create the {@link Worker}'s up-front and return them in a "fair" fashion when calling + * {@link #nextWorker()} + * + */ +public abstract class AbstractNioWorkerPool implements WorkerPool , ExternalResourceReleasable { + + private final AbstractNioWorker[] workers; + private final AtomicInteger workerIndex = new AtomicInteger(); + private final Executor workerExecutor; + + /** + * Create a new instance + * + * @param workerExecutor the {@link Executor} to use for the {@link Worker}'s + * @param allowShutdownOnIdle allow the {@link Worker}'s to shutdown when there is not {@link Channel} is registered with it + * @param workerCount the count of {@link Worker}'s to create + */ + AbstractNioWorkerPool(Executor workerExecutor, int workerCount, boolean allowShutDownOnIdle) { + if (workerExecutor == null) { + throw new NullPointerException("workerExecutor"); + } + if (workerCount <= 0) { + throw new IllegalArgumentException( + "workerCount (" + workerCount + ") " + + "must be a positive integer."); + } + workers = new AbstractNioWorker[workerCount]; + + for (int i = 0; i < workers.length; i++) { + workers[i] = createWorker(workerExecutor, allowShutDownOnIdle); + } + this.workerExecutor = workerExecutor; + + } + + /** + * Create a new {@link Worker} which uses the given {@link Executor} to service IO + * + * + * @param executor the {@link Executor} to use + * @param allowShutdownOnIdle allow the {@link Worker} to shutdown when there is not {@link Channel} is registered with it + * @return worker the new {@link Worker} + */ + protected abstract E createWorker(Executor executor, boolean allowShutdownOnIdle); + + @SuppressWarnings("unchecked") + public E nextWorker() { + return (E) workers[Math.abs(workerIndex.getAndIncrement() % workers.length)]; + } + + + public void releaseExternalResources() { + ExecutorUtil.terminate(workerExecutor); + } + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioChannelConfig.java index b9156a3c10..3f963878fd 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioChannelConfig.java @@ -1,82 +1,82 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.nio; - -import java.nio.ByteBuffer; -import java.nio.channels.WritableByteChannel; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelConfig; - -/** - * Special {@link ChannelConfig} sub-type which offers extra methods which are useful for NIO. - * - */ -public interface NioChannelConfig extends ChannelConfig { - - /** - * Returns the high water mark of the write buffer. If the number of bytes - * queued in the write buffer exceeds this value, {@link Channel#isWritable()} - * will start to return {@code true}. - */ - int getWriteBufferHighWaterMark(); - - /** - * Sets the high water mark of the write buffer. If the number of bytes - * queued in the write buffer exceeds this value, {@link Channel#isWritable()} - * will start to return {@code true}. - */ - void setWriteBufferHighWaterMark(int writeBufferHighWaterMark); - - /** - * Returns the low water mark of the write buffer. Once the number of bytes - * queued in the write buffer exceeded the - * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then - * dropped down below this value, {@link Channel#isWritable()} will return - * {@code false} again. - */ - int getWriteBufferLowWaterMark(); - - /** - * Sets the low water mark of the write buffer. Once the number of bytes - * queued in the write buffer exceeded the - * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then - * dropped down below this value, {@link Channel#isWritable()} will return - * {@code false} again. - */ - void setWriteBufferLowWaterMark(int writeBufferLowWaterMark); - - /** - * Returns the maximum loop count for a write operation until - * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. - * It is similar to what a spin lock is used for in concurrency programming. - * It improves memory utilization and write throughput depending on - * the platform that JVM runs on. The default value is {@code 16}. - */ - int getWriteSpinCount(); - - /** - * Sets the maximum loop count for a write operation until - * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. - * It is similar to what a spin lock is used for in concurrency programming. - * It improves memory utilization and write throughput depending on - * the platform that JVM runs on. The default value is {@code 16}. - * - * @throws IllegalArgumentException - * if the specified value is {@code 0} or less than {@code 0} - */ - void setWriteSpinCount(int writeSpinCount); -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.nio; + +import java.nio.ByteBuffer; +import java.nio.channels.WritableByteChannel; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelConfig; + +/** + * Special {@link ChannelConfig} sub-type which offers extra methods which are useful for NIO. + * + */ +public interface NioChannelConfig extends ChannelConfig { + + /** + * Returns the high water mark of the write buffer. If the number of bytes + * queued in the write buffer exceeds this value, {@link Channel#isWritable()} + * will start to return {@code true}. + */ + int getWriteBufferHighWaterMark(); + + /** + * Sets the high water mark of the write buffer. If the number of bytes + * queued in the write buffer exceeds this value, {@link Channel#isWritable()} + * will start to return {@code true}. + */ + void setWriteBufferHighWaterMark(int writeBufferHighWaterMark); + + /** + * Returns the low water mark of the write buffer. Once the number of bytes + * queued in the write buffer exceeded the + * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then + * dropped down below this value, {@link Channel#isWritable()} will return + * {@code false} again. + */ + int getWriteBufferLowWaterMark(); + + /** + * Sets the low water mark of the write buffer. Once the number of bytes + * queued in the write buffer exceeded the + * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then + * dropped down below this value, {@link Channel#isWritable()} will return + * {@code false} again. + */ + void setWriteBufferLowWaterMark(int writeBufferLowWaterMark); + + /** + * Returns the maximum loop count for a write operation until + * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. + * It is similar to what a spin lock is used for in concurrency programming. + * It improves memory utilization and write throughput depending on + * the platform that JVM runs on. The default value is {@code 16}. + */ + int getWriteSpinCount(); + + /** + * Sets the maximum loop count for a write operation until + * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. + * It is similar to what a spin lock is used for in concurrency programming. + * It improves memory utilization and write throughput depending on + * the platform that JVM runs on. The default value is {@code 16}. + * + * @throws IllegalArgumentException + * if the specified value is {@code 0} or less than {@code 0} + */ + void setWriteSpinCount(int writeSpinCount); +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketChannelFactory.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketChannelFactory.java index 406906efb6..0bb3ff13c8 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketChannelFactory.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioClientSocketChannelFactory.java @@ -88,8 +88,7 @@ public class NioClientSocketChannelFactory implements ClientSocketChannelFactory private final NioClientSocketPipelineSink sink; /** - * Creates a new {@link NioClientSocketChannelFactory} which uses {@link Executors#newCachedThreadPool()} - * for the worker and boss executors. + * Creates a new {@link NioClientSocketChannelFactory} which uses {@link Executors#newCachedThreadPool()} for the worker and boss executors. * * See {@link #NioClientSocketChannelFactory(Executor, Executor)} */ diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannel.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannel.java index bdc637b281..0eeec0b834 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannel.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramChannel.java @@ -130,8 +130,7 @@ public final class NioDatagramChannel extends AbstractNioChannel workerPool) { this(workerPool, null); @@ -187,8 +186,7 @@ public class NioDatagramChannelFactory implements DatagramChannelFactory { * Creates a new instance. * * @param workerPool - * the {@link WorkerPool} which will be used to obtain the {@link Worker} that execute - * the I/O worker threads + * the {@link WorkerPool} which will be used to obtain the {@link Worker} that execute the I/O worker threads * @param family * the {@link InternetProtocolFamily} to use. This should be used for UDP multicast. * Be aware that this option is only considered when running on java7+ diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramPipelineSink.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramPipelineSink.java index 5a108af50c..589899c372 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramPipelineSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramPipelineSink.java @@ -38,9 +38,8 @@ class NioDatagramPipelineSink extends AbstractNioChannelSink { private final WorkerPool workerPool; /** - * Creates a new {@link NioDatagramPipelineSink} with a the number of {@link NioDatagramWorker}s - * specified in workerCount. The {@link NioDatagramWorker}s take care of reading and writing - * for the {@link NioDatagramChannel}. + * Creates a new {@link NioDatagramPipelineSink} with a the number of {@link NioDatagramWorker}s specified in workerCount. + * The {@link NioDatagramWorker}s take care of reading and writing for the {@link NioDatagramChannel}. * * @param workerExecutor * the {@link Executor} that will run the {@link NioDatagramWorker}s diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramWorkerPool.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramWorkerPool.java index a2e8fa8c9c..7b53e80cf4 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramWorkerPool.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioDatagramWorkerPool.java @@ -1,37 +1,37 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.nio; - -import java.util.concurrent.Executor; - - -/** - * Default implementation which hands of {@link NioDatagramWorker}'s - * - * - */ -public class NioDatagramWorkerPool extends AbstractNioWorkerPool { - - public NioDatagramWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) { - super(executor, workerCount, allowShutdownOnIdle); - } - - @Override - protected NioDatagramWorker createWorker(Executor executor, boolean allowShutdownOnIdle) { - return new NioDatagramWorker(executor, allowShutdownOnIdle); - } - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.nio; + +import java.util.concurrent.Executor; + + +/** + * Default implementation which hands of {@link NioDatagramWorker}'s + * + * + */ +public class NioDatagramWorkerPool extends AbstractNioWorkerPool { + + public NioDatagramWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) { + super(executor, workerCount, allowShutdownOnIdle); + } + + @Override + protected NioDatagramWorker createWorker(Executor executor, boolean allowShutdownOnIdle) { + return new NioDatagramWorker(executor, allowShutdownOnIdle); + } + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketChannelFactory.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketChannelFactory.java index cca91c0647..b18825d9ca 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketChannelFactory.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioServerSocketChannelFactory.java @@ -90,8 +90,7 @@ public class NioServerSocketChannelFactory implements ServerSocketChannelFactory private final ChannelSink sink; /** - * Create a new {@link NioServerSocketChannelFactory} using {@link Executors#newCachedThreadPool()} - * for the boss and worker. + * Create a new {@link NioServerSocketChannelFactory} using {@link Executors#newCachedThreadPool()} for the boss and worker. * * See {@link #NioServerSocketChannelFactory(Executor, Executor)} */ @@ -137,8 +136,7 @@ public class NioServerSocketChannelFactory implements ServerSocketChannelFactory * @param bossExecutor * the {@link Executor} which will execute the boss threads * @param workerPool - * the {@link WorkerPool} which will be used to obtain the {@link NioWorker} that execute - * the I/O worker threads + * the {@link WorkerPool} which will be used to obtain the {@link NioWorker} that execute the I/O worker threads */ public NioServerSocketChannelFactory( Executor bossExecutor, WorkerPool workerPool) { diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java index 343ddc0dcc..8d08e1328e 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannelConfig.java @@ -42,11 +42,9 @@ import org.jboss.netty.channel.socket.SocketChannelConfig; * * {@code "writeSpinCount"}{@link #setWriteSpinCount(int)} * - * {@code "receiveBufferSizePredictor"} - * {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + * {@code "receiveBufferSizePredictor"}{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} * - * {@code "receiveBufferSizePredictorFactory"} - * {@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} + * {@code "receiveBufferSizePredictorFactory"}{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} * * */ diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioWorkerPool.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioWorkerPool.java index 2b08cf1157..950cad76bd 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioWorkerPool.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioWorkerPool.java @@ -1,37 +1,37 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.nio; - -import java.util.concurrent.Executor; - - -/** - * Default implementation which hands of {@link NioWorker}'s - * - * - */ -public class NioWorkerPool extends AbstractNioWorkerPool { - - public NioWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) { - super(executor, workerCount, allowShutdownOnIdle); - } - - @Override - protected NioWorker createWorker(Executor executor, boolean allowShutdownOnIdle) { - return new NioWorker(executor, allowShutdownOnIdle); - } - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.nio; + +import java.util.concurrent.Executor; + + +/** + * Default implementation which hands of {@link NioWorker}'s + * + * + */ +public class NioWorkerPool extends AbstractNioWorkerPool { + + public NioWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) { + super(executor, workerCount, allowShutdownOnIdle); + } + + @Override + protected NioWorker createWorker(Executor executor, boolean allowShutdownOnIdle) { + return new NioWorker(executor, allowShutdownOnIdle); + } + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/ShareableWorkerPool.java b/src/main/java/org/jboss/netty/channel/socket/nio/ShareableWorkerPool.java index e7ced7207b..8664731809 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/ShareableWorkerPool.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/ShareableWorkerPool.java @@ -1,48 +1,47 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.nio; - -import org.jboss.netty.channel.socket.Worker; -import org.jboss.netty.util.ExternalResourceReleasable; - -/** - * This implementation of a {@link WorkerPool} should be used if you plan to share a - * {@link WorkerPool} between different Factories. You will need to call {@link #destroy()} by your - * own once you want to release any resources of it. - * - * - */ -public final class ShareableWorkerPool implements WorkerPool { - - private final WorkerPool wrapped; - - public ShareableWorkerPool(WorkerPool wrapped) { - this.wrapped = wrapped; - } - - public E nextWorker() { - return wrapped.nextWorker(); - } - - /** - * Destroy the {@link ShareableWorkerPool} and release all resources. After this is called its not usable anymore - */ - public void destroy() { - if (wrapped instanceof ExternalResourceReleasable) { - ((ExternalResourceReleasable) wrapped).releaseExternalResources(); - } - } -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.nio; + +import org.jboss.netty.channel.socket.Worker; +import org.jboss.netty.util.ExternalResourceReleasable; + +/** + * This implementation of a {@link WorkerPool} should be used if you plan to share a {@link WorkerPool} between different Factories. You will need to call {@link #destroy()} by your own once + * you want to release any resources of it. + * + * + */ +public final class ShareableWorkerPool implements WorkerPool { + + private final WorkerPool wrapped; + + public ShareableWorkerPool(WorkerPool wrapped) { + this.wrapped = wrapped; + } + + public E nextWorker() { + return wrapped.nextWorker(); + } + + /** + * Destroy the {@link ShareableWorkerPool} and release all resources. After this is called its not usable anymore + */ + public void destroy() { + if (wrapped instanceof ExternalResourceReleasable) { + ((ExternalResourceReleasable) wrapped).releaseExternalResources(); + } + } +} diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/SocketSendBufferPool.java b/src/main/java/org/jboss/netty/channel/socket/nio/SocketSendBufferPool.java index 7924bc7a7f..ea7efa5d3c 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/SocketSendBufferPool.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/SocketSendBufferPool.java @@ -27,6 +27,7 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.CompositeChannelBuffer; import org.jboss.netty.channel.DefaultFileRegion; import org.jboss.netty.channel.FileRegion; +import org.jboss.netty.util.internal.DetectionUtil; final class SocketSendBufferPool { @@ -367,8 +368,7 @@ final class SocketSendBufferPool { public void release() { if (file instanceof DefaultFileRegion) { if (((DefaultFileRegion) file).releaseAfterTransfer()) { - // Make sure the FileRegion resource are released otherwise it may cause a FD - // leak or something similar + // Make sure the FileRegion resource are released otherwise it may cause a FD leak or something similar file.releaseExternalResources(); } } diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/WorkerPool.java b/src/main/java/org/jboss/netty/channel/socket/nio/WorkerPool.java index 4b049ffdba..29053ac5d1 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/WorkerPool.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/WorkerPool.java @@ -1,35 +1,35 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.jboss.netty.channel.socket.nio; - -import org.jboss.netty.channel.socket.Worker; - -/** - * The {@link WorkerPool} is responsible to hand of {@link Worker}'s on demand - * - */ -public interface WorkerPool { - - /** - * Return the next {@link Worker} to use - * - * @return worker - */ - E nextWorker(); - - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package org.jboss.netty.channel.socket.nio; + +import org.jboss.netty.channel.socket.Worker; + +/** + * The {@link WorkerPool} is responsible to hand of {@link Worker}'s on demand + * + */ +public interface WorkerPool { + + /** + * Return the next {@link Worker} to use + * + * @return worker + */ + E nextWorker(); + + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannel.java b/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannel.java index 56da38bf35..d64ee29a22 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannel.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannel.java @@ -1,117 +1,117 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.oio; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.SocketAddress; - -import org.jboss.netty.channel.AbstractChannel; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFactory; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.ChannelSink; -import org.jboss.netty.channel.socket.Worker; - -abstract class AbstractOioChannel extends AbstractChannel { - private volatile InetSocketAddress localAddress; - volatile InetSocketAddress remoteAddress; - volatile Thread workerThread; - volatile Worker worker; - - final Object interestOpsLock = new Object(); - - AbstractOioChannel( - Channel parent, - ChannelFactory factory, - ChannelPipeline pipeline, - ChannelSink sink) { - super(parent, factory, pipeline, sink); - } - - @Override - protected boolean setClosed() { - return super.setClosed(); - } - - @Override - protected void setInterestOpsNow(int interestOps) { - super.setInterestOpsNow(interestOps); - } - - @Override - public ChannelFuture write(Object message, SocketAddress remoteAddress) { - if (remoteAddress == null || remoteAddress.equals(getRemoteAddress())) { - return super.write(message, null); - } else { - return super.write(message, remoteAddress); - } - } - - - public boolean isBound() { - return isOpen() && isSocketBound(); - } - - - public boolean isConnected() { - return isOpen() && isSocketConnected(); - } - - - - public InetSocketAddress getLocalAddress() { - InetSocketAddress localAddress = this.localAddress; - if (localAddress == null) { - try { - this.localAddress = localAddress = getLocalSocketAddress(); - } catch (Throwable t) { - // Sometimes fails on a closed socket in Windows. - return null; - } - } - return localAddress; - } - - - public InetSocketAddress getRemoteAddress() { - InetSocketAddress remoteAddress = this.remoteAddress; - if (remoteAddress == null) { - try { - this.remoteAddress = remoteAddress = - getRemoteSocketAddress(); - } catch (Throwable t) { - // Sometimes fails on a closed socket in Windows. - return null; - } - } - return remoteAddress; - } - - abstract boolean isSocketBound(); - - abstract boolean isSocketConnected(); - - abstract boolean isSocketClosed(); - - abstract InetSocketAddress getLocalSocketAddress() throws Exception; - - abstract InetSocketAddress getRemoteSocketAddress() throws Exception; - - abstract void closeSocket() throws IOException; - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.oio; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +import org.jboss.netty.channel.AbstractChannel; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFactory; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelSink; +import org.jboss.netty.channel.socket.Worker; + +abstract class AbstractOioChannel extends AbstractChannel { + private volatile InetSocketAddress localAddress; + volatile InetSocketAddress remoteAddress; + volatile Thread workerThread; + volatile Worker worker; + + final Object interestOpsLock = new Object(); + + AbstractOioChannel( + Channel parent, + ChannelFactory factory, + ChannelPipeline pipeline, + ChannelSink sink) { + super(parent, factory, pipeline, sink); + } + + @Override + protected boolean setClosed() { + return super.setClosed(); + } + + @Override + protected void setInterestOpsNow(int interestOps) { + super.setInterestOpsNow(interestOps); + } + + @Override + public ChannelFuture write(Object message, SocketAddress remoteAddress) { + if (remoteAddress == null || remoteAddress.equals(getRemoteAddress())) { + return super.write(message, null); + } else { + return super.write(message, remoteAddress); + } + } + + + public boolean isBound() { + return isOpen() && isSocketBound(); + } + + + public boolean isConnected() { + return isOpen() && isSocketConnected(); + } + + + + public InetSocketAddress getLocalAddress() { + InetSocketAddress localAddress = this.localAddress; + if (localAddress == null) { + try { + this.localAddress = localAddress = getLocalSocketAddress(); + } catch (Throwable t) { + // Sometimes fails on a closed socket in Windows. + return null; + } + } + return localAddress; + } + + + public InetSocketAddress getRemoteAddress() { + InetSocketAddress remoteAddress = this.remoteAddress; + if (remoteAddress == null) { + try { + this.remoteAddress = remoteAddress = + getRemoteSocketAddress(); + } catch (Throwable t) { + // Sometimes fails on a closed socket in Windows. + return null; + } + } + return remoteAddress; + } + + abstract boolean isSocketBound(); + + abstract boolean isSocketConnected(); + + abstract boolean isSocketClosed(); + + abstract InetSocketAddress getLocalSocketAddress() throws Exception; + + abstract InetSocketAddress getRemoteSocketAddress() throws Exception; + + abstract void closeSocket() throws IOException; + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannelSink.java b/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannelSink.java index 00f4107e2f..e74b2c5dc3 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannelSink.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioChannelSink.java @@ -1,57 +1,57 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ - -package org.jboss.netty.channel.socket.oio; - -import org.jboss.netty.channel.AbstractChannelSink; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelEvent; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.channel.socket.ChannelRunnableWrapper; -import org.jboss.netty.channel.socket.Worker; - -public abstract class AbstractOioChannelSink extends AbstractChannelSink { - - @Override - public ChannelFuture execute(final ChannelPipeline pipeline, final Runnable task) { - Channel ch = pipeline.getChannel(); - if (ch instanceof AbstractOioChannel) { - AbstractOioChannel channel = (AbstractOioChannel) ch; - Worker worker = channel.worker; - if (worker != null) { - ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task); - channel.worker.executeInIoThread(wrapper); - return wrapper; - } - } - - return super.execute(pipeline, task); - - - } - - @Override - protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) { - Channel channel = event.getChannel(); - boolean fireLater = false; - if (channel instanceof AbstractOioChannel) { - fireLater = !AbstractOioWorker.isIoThread((AbstractOioChannel) channel); - } - return fireLater; - } - -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package org.jboss.netty.channel.socket.oio; + +import org.jboss.netty.channel.AbstractChannelSink; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.socket.ChannelRunnableWrapper; +import org.jboss.netty.channel.socket.Worker; + +public abstract class AbstractOioChannelSink extends AbstractChannelSink { + + @Override + public ChannelFuture execute(final ChannelPipeline pipeline, final Runnable task) { + Channel ch = pipeline.getChannel(); + if (ch instanceof AbstractOioChannel) { + AbstractOioChannel channel = (AbstractOioChannel) ch; + Worker worker = channel.worker; + if (worker != null) { + ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task); + channel.worker.executeInIoThread(wrapper); + return wrapper; + } + } + + return super.execute(pipeline, task); + + + } + + @Override + protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) { + Channel channel = event.getChannel(); + boolean fireLater = false; + if (channel instanceof AbstractOioChannel) { + fireLater = !AbstractOioWorker.isIoThread((AbstractOioChannel) channel); + } + return fireLater; + } + +} diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioWorker.java b/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioWorker.java index d5d85fe6f2..b2485fd6df 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioWorker.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/AbstractOioWorker.java @@ -1,243 +1,241 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.channel.socket.oio; - -import static org.jboss.netty.channel.Channels.*; - -import java.io.IOException; -import java.util.Queue; - -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelFuture; -import org.jboss.netty.channel.Channels; -import org.jboss.netty.channel.socket.Worker; -import org.jboss.netty.util.internal.QueueFactory; - -/** - * Abstract base class for Oio-Worker implementations - * - * @param {@link AbstractOioChannel} - */ -abstract class AbstractOioWorker implements Worker { - - private final Queue eventQueue = QueueFactory.createQueue(Runnable.class); - - protected final C channel; - - /** - * If this worker has been started thread will be a reference to the thread - * used when starting. i.e. the current thread when the run method is executed. - */ - protected volatile Thread thread; - - private volatile boolean done; - - public AbstractOioWorker(C channel) { - this.channel = channel; - channel.worker = this; - } - - - public void run() { - thread = channel.workerThread = Thread.currentThread(); - - while (channel.isOpen()) { - synchronized (channel.interestOpsLock) { - while (!channel.isReadable()) { - try { - // notify() is not called at all. - // close() and setInterestOps() calls Thread.interrupt() - channel.interestOpsLock.wait(); - } catch (InterruptedException e) { - if (!channel.isOpen()) { - break; - } - } - } - } - - boolean cont = false; - try { - cont = process(); - } catch (Throwable t) { - if (!channel.isSocketClosed()) { - fireExceptionCaught(channel, t); - } - } finally { - processEventQueue(); - - if (!cont) { - break; - } - } - } - - // Setting the workerThread to null will prevent any channel - // operations from interrupting this thread from now on. - channel.workerThread = null; - - // Clean up. - close(channel, succeededFuture(channel), true); - - // Mark the worker event loop as done so we know that we need to run tasks directly and not queue them - // See #287 - done = true; - - // just to make we don't have something left - processEventQueue(); - - } - - static boolean isIoThread(AbstractOioChannel channel) { - return Thread.currentThread() == channel.workerThread; - } - - - public void executeInIoThread(Runnable task) { - // check if the current thread is the worker thread - // - // Also check if the event loop of the worker is complete. If so we need to run the task now. - // See #287 - if (Thread.currentThread() == thread || done) { - task.run(); - } else { - boolean added = eventQueue.offer(task); - - if (added) { - // as we set the SO_TIMEOUT to 1 second this task will get picked up in 1 second at latest - } - } - } - - private void processEventQueue() { - for (;;) { - final Runnable task = eventQueue.poll(); - if (task == null) { - break; - } - task.run(); - } - } - - - /** - * Process the incoming messages and also is responsible for call - * {@link Channels#fireMessageReceived(Channel, Object)} once a message was processed without - * errors. - * - * @return continue returns true as long as this worker should continue to try - * processing incoming messages - * @throws IOException - */ - abstract boolean process() throws IOException; - - static void setInterestOps( - AbstractOioChannel channel, ChannelFuture future, int interestOps) { - boolean iothread = isIoThread(channel); - - // Override OP_WRITE flag - a user cannot change this flag. - interestOps &= ~Channel.OP_WRITE; - interestOps |= channel.getInterestOps() & Channel.OP_WRITE; - - boolean changed = false; - try { - if (channel.getInterestOps() != interestOps) { - if ((interestOps & Channel.OP_READ) != 0) { - channel.setInterestOpsNow(Channel.OP_READ); - } else { - channel.setInterestOpsNow(Channel.OP_NONE); - } - changed = true; - } - - future.setSuccess(); - if (changed) { - synchronized (channel.interestOpsLock) { - channel.setInterestOpsNow(interestOps); - - // Notify the worker so it stops or continues reading. - Thread currentThread = Thread.currentThread(); - Thread workerThread = channel.workerThread; - if (workerThread != null && currentThread != workerThread) { - workerThread.interrupt(); - } - } - if (iothread) { - fireChannelInterestChanged(channel); - } else { - fireChannelInterestChangedLater(channel); - } - } - } catch (Throwable t) { - future.setFailure(t); - if (iothread) { - fireExceptionCaught(channel, t); - } else { - fireExceptionCaughtLater(channel, t); - } - } - } - - static void close(AbstractOioChannel channel, ChannelFuture future) { - close(channel, future, isIoThread(channel)); - } - - private static void close(AbstractOioChannel channel, ChannelFuture future, boolean iothread) { - boolean connected = channel.isConnected(); - boolean bound = channel.isBound(); - - try { - channel.closeSocket(); - if (channel.setClosed()) { - future.setSuccess(); - if (connected) { - // Notify the worker so it stops reading. - Thread currentThread = Thread.currentThread(); - Thread workerThread = channel.workerThread; - if (workerThread != null && currentThread != workerThread) { - workerThread.interrupt(); - } - if (iothread) { - fireChannelDisconnected(channel); - } else { - fireChannelDisconnectedLater(channel); - } - } - if (bound) { - if (iothread) { - fireChannelUnbound(channel); - } else { - fireChannelUnboundLater(channel); - } - } - if (iothread) { - fireChannelClosed(channel); - } else { - fireChannelClosedLater(channel); - } - } else { - future.setSuccess(); - } - } catch (Throwable t) { - future.setFailure(t); - if (iothread) { - fireExceptionCaught(channel, t); - } else { - fireExceptionCaughtLater(channel, t); - } - } - } -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.channel.socket.oio; + +import static org.jboss.netty.channel.Channels.*; + +import java.io.IOException; +import java.util.Queue; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.Channels; +import org.jboss.netty.channel.socket.Worker; +import org.jboss.netty.util.internal.QueueFactory; + +/** + * Abstract base class for Oio-Worker implementations + * + * @param {@link AbstractOioChannel} + */ +abstract class AbstractOioWorker implements Worker { + + private final Queue eventQueue = QueueFactory.createQueue(Runnable.class); + + protected final C channel; + + /** + * If this worker has been started thread will be a reference to the thread + * used when starting. i.e. the current thread when the run method is executed. + */ + protected volatile Thread thread; + + private volatile boolean done; + + public AbstractOioWorker(C channel) { + this.channel = channel; + channel.worker = this; + } + + + public void run() { + thread = channel.workerThread = Thread.currentThread(); + + while (channel.isOpen()) { + synchronized (channel.interestOpsLock) { + while (!channel.isReadable()) { + try { + // notify() is not called at all. + // close() and setInterestOps() calls Thread.interrupt() + channel.interestOpsLock.wait(); + } catch (InterruptedException e) { + if (!channel.isOpen()) { + break; + } + } + } + } + + boolean cont = false; + try { + cont = process(); + } catch (Throwable t) { + if (!channel.isSocketClosed()) { + fireExceptionCaught(channel, t); + } + } finally { + processEventQueue(); + + if (!cont) { + break; + } + } + } + + // Setting the workerThread to null will prevent any channel + // operations from interrupting this thread from now on. + channel.workerThread = null; + + // Clean up. + close(channel, succeededFuture(channel), true); + + // Mark the worker event loop as done so we know that we need to run tasks directly and not queue them + // See #287 + done = true; + + // just to make we don't have something left + processEventQueue(); + + } + + static boolean isIoThread(AbstractOioChannel channel) { + return Thread.currentThread() == channel.workerThread; + } + + + public void executeInIoThread(Runnable task) { + // check if the current thread is the worker thread + // + // Also check if the event loop of the worker is complete. If so we need to run the task now. + // See #287 + if (Thread.currentThread() == thread || done) { + task.run(); + } else { + boolean added = eventQueue.offer(task); + + if (added) { + // as we set the SO_TIMEOUT to 1 second this task will get picked up in 1 second at latest + } + } + } + + private void processEventQueue() { + for (;;) { + final Runnable task = eventQueue.poll(); + if (task == null) { + break; + } + task.run(); + } + } + + + /** + * Process the incoming messages and also is responsible for call {@link Channels#fireMessageReceived(Channel, Object)} once a message + * was processed without errors. + * + * @return continue returns true as long as this worker should continue to try processing incoming messages + * @throws IOException + */ + abstract boolean process() throws IOException; + + static void setInterestOps( + AbstractOioChannel channel, ChannelFuture future, int interestOps) { + boolean iothread = isIoThread(channel); + + // Override OP_WRITE flag - a user cannot change this flag. + interestOps &= ~Channel.OP_WRITE; + interestOps |= channel.getInterestOps() & Channel.OP_WRITE; + + boolean changed = false; + try { + if (channel.getInterestOps() != interestOps) { + if ((interestOps & Channel.OP_READ) != 0) { + channel.setInterestOpsNow(Channel.OP_READ); + } else { + channel.setInterestOpsNow(Channel.OP_NONE); + } + changed = true; + } + + future.setSuccess(); + if (changed) { + synchronized (channel.interestOpsLock) { + channel.setInterestOpsNow(interestOps); + + // Notify the worker so it stops or continues reading. + Thread currentThread = Thread.currentThread(); + Thread workerThread = channel.workerThread; + if (workerThread != null && currentThread != workerThread) { + workerThread.interrupt(); + } + } + if (iothread) { + fireChannelInterestChanged(channel); + } else { + fireChannelInterestChangedLater(channel); + } + } + } catch (Throwable t) { + future.setFailure(t); + if (iothread) { + fireExceptionCaught(channel, t); + } else { + fireExceptionCaughtLater(channel, t); + } + } + } + + static void close(AbstractOioChannel channel, ChannelFuture future) { + close(channel, future, isIoThread(channel)); + } + + private static void close(AbstractOioChannel channel, ChannelFuture future, boolean iothread) { + boolean connected = channel.isConnected(); + boolean bound = channel.isBound(); + + try { + channel.closeSocket(); + if (channel.setClosed()) { + future.setSuccess(); + if (connected) { + // Notify the worker so it stops reading. + Thread currentThread = Thread.currentThread(); + Thread workerThread = channel.workerThread; + if (workerThread != null && currentThread != workerThread) { + workerThread.interrupt(); + } + if (iothread) { + fireChannelDisconnected(channel); + } else { + fireChannelDisconnectedLater(channel); + } + } + if (bound) { + if (iothread) { + fireChannelUnbound(channel); + } else { + fireChannelUnboundLater(channel); + } + } + if (iothread) { + fireChannelClosed(channel); + } else { + fireChannelClosedLater(channel); + } + } else { + future.setSuccess(); + } + } catch (Throwable t) { + future.setFailure(t); + if (iothread) { + fireExceptionCaught(channel, t); + } else { + fireExceptionCaughtLater(channel, t); + } + } + } +} diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketChannelFactory.java b/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketChannelFactory.java index 2e74fe4e16..405f60e3fc 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketChannelFactory.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/OioServerSocketChannelFactory.java @@ -91,8 +91,7 @@ public class OioServerSocketChannelFactory implements ServerSocketChannelFactory private final ChannelSink sink; /** - * Create a new {@link OioServerSocketChannelFactory} with a {@link Executors#newCachedThreadPool()} - * for the boss and worker executor. + * Create a new {@link OioServerSocketChannelFactory} with a {@link Executors#newCachedThreadPool()} for the boss and worker executor. * * See {@link #OioServerSocketChannelFactory(Executor, Executor)} */ diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/OioWorker.java b/src/main/java/org/jboss/netty/channel/socket/oio/OioWorker.java index 78b5512d9c..1d3cc8c685 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/OioWorker.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/OioWorker.java @@ -94,8 +94,8 @@ class OioWorker extends AbstractOioWorker { try { int length = 0; - // Add support to write a FileRegion. This in fact will not give any performance gain - // but at least it not fail and we did the best to emulate it + // Add support to write a FileRegion. This in fact will not give any performance gain but at least it not fail and + // we did the best to emulate it if (message instanceof FileRegion) { FileRegion fr = (FileRegion) message; try { diff --git a/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java b/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java index c908936779..69ccf3c430 100644 --- a/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java +++ b/src/main/java/org/jboss/netty/example/http/file/HttpStaticFileServerHandler.java @@ -138,8 +138,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelUpstreamHandler { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince); - // Only compare up to the second because the datetime format we send to the client does - // not have milliseconds + // Only compare up to the second because the datetime format we send to the client does not have milliseconds long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000; long fileLastModifiedSeconds = file.lastModified() / 1000; if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { @@ -298,8 +297,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelUpstreamHandler { time.add(Calendar.SECOND, HTTP_CACHE_SECONDS); response.setHeader(HttpHeaders.Names.EXPIRES, dateFormatter.format(time.getTime())); response.setHeader(HttpHeaders.Names.CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS); - response.setHeader( - HttpHeaders.Names.LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified()))); + response.setHeader(HttpHeaders.Names.LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified()))); } /** diff --git a/src/main/java/org/jboss/netty/example/http/snoop/HttpSnoopServerHandler.java b/src/main/java/org/jboss/netty/example/http/snoop/HttpSnoopServerHandler.java index d06a8cc456..af5ed1bb9c 100644 --- a/src/main/java/org/jboss/netty/example/http/snoop/HttpSnoopServerHandler.java +++ b/src/main/java/org/jboss/netty/example/http/snoop/HttpSnoopServerHandler.java @@ -132,8 +132,7 @@ public class HttpSnoopServerHandler extends SimpleChannelUpstreamHandler { if (keepAlive) { // Add 'Content-Length' header only for a keep-alive connection. response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes()); - // Add keep alive header as per: - // - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection + // Add keep alive header as per http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } diff --git a/src/main/java/org/jboss/netty/example/http/upload/HttpUploadServerHandler.java b/src/main/java/org/jboss/netty/example/http/upload/HttpUploadServerHandler.java index 4e844afdfb..e4d4d31913 100644 --- a/src/main/java/org/jboss/netty/example/http/upload/HttpUploadServerHandler.java +++ b/src/main/java/org/jboss/netty/example/http/upload/HttpUploadServerHandler.java @@ -430,8 +430,7 @@ public class HttpUploadServerHandler extends SimpleChannelUpstreamHandler { responseContent .append("Fill with value:
"); responseContent - .append("Fill with file (only file name will be transmitted):
" + - ""); + .append("Fill with file (only file name will be transmitted):
"); responseContent.append(""); responseContent .append(""); diff --git a/src/main/java/org/jboss/netty/example/http/websocketx/server/WebSocketServerIndexPage.java b/src/main/java/org/jboss/netty/example/http/websocketx/server/WebSocketServerIndexPage.java index 866a80427d..a841e80b17 100644 --- a/src/main/java/org/jboss/netty/example/http/websocketx/server/WebSocketServerIndexPage.java +++ b/src/main/java/org/jboss/netty/example/http/websocketx/server/WebSocketServerIndexPage.java @@ -27,50 +27,67 @@ public final class WebSocketServerIndexPage { private static final String NEWLINE = "\r\n"; public static ChannelBuffer getContent(String webSocketLocation) { - return ChannelBuffers.copiedBuffer( - "Web Socket Test" + NEWLINE + - "" + NEWLINE + - "" + NEWLINE + - "

" + NEWLINE + - "" + - "" + NEWLINE + - "

Output

" + NEWLINE + - "" + NEWLINE + - "
" + NEWLINE + - "" + NEWLINE + - "" + NEWLINE, CharsetUtil.US_ASCII); + return ChannelBuffers + .copiedBuffer( + "Web Socket Test" + + NEWLINE + + "" + + NEWLINE + + "" + + NEWLINE + + "
" + + NEWLINE + + "" + + "" + + NEWLINE + "

Output

" + NEWLINE + + "" + + NEWLINE + "
" + NEWLINE + "" + NEWLINE + "" + NEWLINE, + CharsetUtil.US_ASCII); } private WebSocketServerIndexPage() { diff --git a/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java b/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java index de7759eff0..1bbb03751c 100644 --- a/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java +++ b/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerHandler.java @@ -29,7 +29,6 @@ import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; -import org.jboss.netty.example.http.websocketx.server.WebSocketServerIndexPage; import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpRequest; @@ -76,7 +75,7 @@ public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler { if (req.getUri().equals("/")) { HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); - ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); + ChannelBuffer content = WebSocketSslServerIndexPage.getContent(getWebSocketLocation(req)); res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); setContentLength(res, content.readableBytes()); diff --git a/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java b/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java new file mode 100644 index 0000000000..96230a5351 --- /dev/null +++ b/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java @@ -0,0 +1,96 @@ +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.example.http.websocketx.sslserver; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.util.CharsetUtil; + +/** + * Generates the demo HTML page which is served at http://localhost:8080/ + */ +public final class WebSocketSslServerIndexPage { + + private static final String NEWLINE = "\r\n"; + + public static ChannelBuffer getContent(String webSocketLocation) { + return ChannelBuffers + .copiedBuffer( + "Web Socket Test" + + NEWLINE + + "" + + NEWLINE + + "" + + NEWLINE + + "
" + + NEWLINE + + "" + + "" + + NEWLINE + "

Output

" + NEWLINE + + "" + + NEWLINE + "
" + NEWLINE + "" + NEWLINE + "" + NEWLINE, + CharsetUtil.US_ASCII); + } + + private WebSocketSslServerIndexPage() { + // Unused + } +} diff --git a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClient.java b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClient.java index 65c56b5bd7..8cd31d3bfb 100644 --- a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClient.java +++ b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentClient.java @@ -34,7 +34,7 @@ import org.jboss.netty.util.CharsetUtil; * A UDP broadcast client that asks for a quote of the moment (QOTM) to * {@link QuoteOfTheMomentServer}. * - * Inspired by the official Java tutorial. + * Inspired by the official Java tutorial. */ public class QuoteOfTheMomentClient { diff --git a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServer.java b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServer.java index ad65eacd1a..47a55f59b9 100644 --- a/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServer.java +++ b/src/main/java/org/jboss/netty/example/qotm/QuoteOfTheMomentServer.java @@ -32,7 +32,7 @@ import org.jboss.netty.util.CharsetUtil; * A UDP server that responds to the QOTM (quote of the moment) request to a * {@link QuoteOfTheMomentClient}. * - * Inspired by the official Java tutorial. + * Inspired by the official Java tutorial. */ public class QuoteOfTheMomentServer { diff --git a/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFactory.java b/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFactory.java index 39567a6880..e427a74f99 100644 --- a/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFactory.java +++ b/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFactory.java @@ -16,7 +16,6 @@ package org.jboss.netty.example.securechat; import java.security.KeyStore; -import java.security.SecureRandom; import java.security.Security; import javax.net.ssl.KeyManager; @@ -43,10 +42,10 @@ import org.jboss.netty.handler.ssl.SslHandler; * {@link SslHandler}. *
  • When initializing an {@link SSLContext} on the client side, * specify the {@link KeyManager} that contains the client certificate as - * the first argument of {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}.
  • + * the first argument of {@link SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)}. *
  • When initializing an {@link SSLContext} on the server side, * specify the proper {@link TrustManager} as the second argument of - * {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)} + * {@link SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)} * to validate the client certificate.
  • * */ diff --git a/src/main/java/org/jboss/netty/handler/codec/base64/Base64.java b/src/main/java/org/jboss/netty/handler/codec/base64/Base64.java index b9d9d574e8..2077d3562a 100644 --- a/src/main/java/org/jboss/netty/handler/codec/base64/Base64.java +++ b/src/main/java/org/jboss/netty/handler/codec/base64/Base64.java @@ -28,9 +28,7 @@ import org.jboss.netty.buffer.HeapChannelBufferFactory; * Base64 notation. *

    * The encoding and decoding algorithm in this class has been derived from - * Robert Harder's Public Domain - * Base64 Encoder/Decoder. - * + * Robert Harder's Public Domain Base64 Encoder/Decoder. * @apiviz.landmark * @apiviz.uses org.jboss.netty.handler.codec.base64.Base64Dialect */ @@ -127,8 +125,7 @@ public final class Base64 { return encode(src, off, len, Base64Dialect.STANDARD, bufferFactory); } - public static ChannelBuffer encode( - ChannelBuffer src, int off, int len, Base64Dialect dialect, ChannelBufferFactory bufferFactory) { + public static ChannelBuffer encode(ChannelBuffer src, int off, int len, Base64Dialect dialect, ChannelBufferFactory bufferFactory) { return encode(src, off, len, breakLines(dialect), dialect, bufferFactory); } diff --git a/src/main/java/org/jboss/netty/handler/codec/base64/Base64Dialect.java b/src/main/java/org/jboss/netty/handler/codec/base64/Base64Dialect.java index edaa007f8f..2293606bea 100644 --- a/src/main/java/org/jboss/netty/handler/codec/base64/Base64Dialect.java +++ b/src/main/java/org/jboss/netty/handler/codec/base64/Base64Dialect.java @@ -23,8 +23,7 @@ package org.jboss.netty.handler.codec.base64; * Enumeration of supported Base64 dialects. *

    * The internal lookup tables in this class has been derived from - * Robert Harder's Public Domain - * Base64 Encoder/Decoder. + * Robert Harder's Public Domain Base64 Encoder/Decoder. */ public enum Base64Dialect { /** diff --git a/src/main/java/org/jboss/netty/handler/codec/embedder/EmbeddedChannel.java b/src/main/java/org/jboss/netty/handler/codec/embedder/EmbeddedChannel.java index 81e8f307e2..a709ec6179 100644 --- a/src/main/java/org/jboss/netty/handler/codec/embedder/EmbeddedChannel.java +++ b/src/main/java/org/jboss/netty/handler/codec/embedder/EmbeddedChannel.java @@ -25,8 +25,7 @@ import org.jboss.netty.channel.DefaultChannelConfig; /** * TODO Make EmbeddedChannel implement ChannelConfig and ChannelSink to reduce overhead. - * TODO Do not extend AbstractChannel to reduce overhead and remove the internal-use-only - * constructor in AbstractChannel. + * TODO Do not extend AbstractChannel to reduce overhead and remove the internal-use-only constructor in AbstractChannel. */ class EmbeddedChannel extends AbstractChannel { diff --git a/src/main/java/org/jboss/netty/handler/codec/embedder/EncoderEmbedder.java b/src/main/java/org/jboss/netty/handler/codec/embedder/EncoderEmbedder.java index b6a1928de9..8c244dac38 100644 --- a/src/main/java/org/jboss/netty/handler/codec/embedder/EncoderEmbedder.java +++ b/src/main/java/org/jboss/netty/handler/codec/embedder/EncoderEmbedder.java @@ -34,7 +34,7 @@ import org.jboss.netty.util.CharsetUtil; *

      * String data = "foobar";
      *
    - * {@link EncoderEmbedder}<{@link ChannelBuffer}> embedder = new {@link EncoderEmbedder}<>(
    + * {@link EncoderEmbedder}<{@link ChannelBuffer}> embedder = new {@link EncoderEmbedder}<{@link ChannelBuffer}>(
      *         new {@link Base64Encoder}(), new {@link StringEncoder}());
      *
      * embedder.offer(data);
    diff --git a/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java b/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java
    index bdf42f4ef8..6bc41d2400 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/frame/FixedLengthFrameDecoder.java
    @@ -51,11 +51,8 @@ public class FixedLengthFrameDecoder extends FrameDecoder {
         /**
          * Creates a new instance.
          *
    -     * @param frameLength
    -     *        the length of the frame
    -     * @param allocateFullBuffer
    -     *        true if the cumulative {@link ChannelBuffer} should use the
    -     *        {@link #frameLength} as its initial size
    +     * @param frameLength  the length of the frame
    +     * @param allocateFullBuffer true if the cumulative {@link ChannelBuffer} should use the {@link #frameLength} as its initial size
          */
         public FixedLengthFrameDecoder(int frameLength, boolean allocateFullBuffer) {
             if (frameLength <= 0) {
    diff --git a/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java b/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java
    index 3e313ba9c9..6499a21003 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/frame/FrameDecoder.java
    @@ -214,8 +214,7 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
                     callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
                 } finally {
                     if (input.readable()) {
    -                    // seems like there is something readable left in the input buffer. So create
    -                    // the cumulation buffer and copy the input into it
    +                    // seems like there is something readable left in the input buffer. So create the cumulation buffer and copy the input into it
                         (cumulation = newCumulationBuffer(ctx, input.readableBytes())).writeBytes(input);
                     }
                 }
    @@ -351,8 +350,7 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
             }
         }
     
    -    protected final void unfoldAndFireMessageReceived(
    -            ChannelHandlerContext context, SocketAddress remoteAddress, Object result) {
    +    protected final void unfoldAndFireMessageReceived(ChannelHandlerContext context, SocketAddress remoteAddress, Object result) {
             if (unfold) {
                 if (result instanceof Object[]) {
                     for (Object r: (Object[]) result) {
    @@ -371,8 +369,8 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
         }
     
         /**
    -     * Gets called on {@link #channelDisconnected(ChannelHandlerContext, ChannelStateEvent)} and
    -     * {@link #channelClosed(ChannelHandlerContext, ChannelStateEvent)}
    +     * Gets called on {@link #channelDisconnected(ChannelHandlerContext, ChannelStateEvent)} and {@link #channelClosed(ChannelHandlerContext, ChannelStateEvent)}
    +     *
          */
         protected void cleanup(ChannelHandlerContext ctx, ChannelStateEvent e)
                 throws Exception {
    @@ -422,8 +420,7 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
          */
         public void replace(String handlerName, ChannelHandler handler) {
             if (ctx == null) {
    -            throw new IllegalStateException(
    -                    "Replace cann only be called once the FrameDecoder is added to the ChannelPipeline");
    +            throw new IllegalStateException("Replace cann only be called once the FrameDecoder is added to the ChannelPipeline");
             }
             ChannelPipeline pipeline = ctx.getPipeline();
             pipeline.addAfter(ctx.getName(), handlerName, handler);
    diff --git a/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java
    index 2f3d1ad423..39acbc2cc1 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/http/CookieDecoder.java
    @@ -41,8 +41,8 @@ import java.util.regex.Pattern;
      */
     public class CookieDecoder {
     
    -    private static final Pattern PATTERN = Pattern.compile(
    -            "(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))");
    +    private static final Pattern PATTERN =
    +        Pattern.compile("(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))");
     
         private static final String COMMA = ",";
     
    diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpClientCodec.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpClientCodec.java
    index 51352742d8..ba05c91d38 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpClientCodec.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpClientCodec.java
    @@ -219,8 +219,7 @@ public class HttpClientCodec implements ChannelUpstreamHandler,
                 if (failOnMissingResponse) {
                     long missingResponses = requestResponseCounter.get();
                     if (missingResponses > 0) {
    -                    throw new PrematureChannelClosureException(
    -                            "Channel closed but still missing " + missingResponses + " response(s)");
    +                    throw new PrematureChannelClosureException("Channel closed but still missing " + missingResponses + " response(s)");
                     }
                 }
             }
    diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentEncoder.java
    index fdbcb794cb..578bbeb2d0 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpContentEncoder.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpContentEncoder.java
    @@ -150,8 +150,7 @@ public abstract class HttpContentEncoder extends SimpleChannelHandler {
                         // the last product on closure,
                         if (lastProduct.readable()) {
                             Channels.write(
    -                                ctx, Channels.succeededFuture(e.getChannel()),
    -                                new DefaultHttpChunk(lastProduct), e.getRemoteAddress());
    +                                ctx, Channels.succeededFuture(e.getChannel()), new DefaultHttpChunk(lastProduct), e.getRemoteAddress());
                         }
     
                         // Emit the last chunk.
    diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java
    index bbfeed3415..4a11def611 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageDecoder.java
    @@ -167,8 +167,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder {
         /**
    -     * The OPTIONS method represents a request for information about the communication options
    -     * available on the request/response chain identified by the Request-URI. This method allows
    -     * the client to determine the options and/or requirements associated with a resource, or the
    -     * capabilities of a server, without implying a resource action or initiating a resource
    -     * retrieval.
    +     * The OPTIONS method represents a request for information about the communication options available on the request/response
    +     * chain identified by the Request-URI. This method allows the client to determine the options and/or requirements
    +     * associated with a resource, or the capabilities of a server, without implying a resource action or initiating a
    +     * resource retrieval.
          */
         public static final HttpMethod OPTIONS = new HttpMethod("OPTIONS");
     
         /**
    -     * The GET method means retrieve whatever information (in the form of an entity) is identified
    -     * by the Request-URI.  If the Request-URI refers to a data-producing process, it is the
    -     * produced data which shall be returned as the entity in the response and not the source text
    -     * of the process, unless that text happens to be the output of the process.
    +     * The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.
    +     * If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity
    +     * in the response and not the source text of the process, unless that text happens to be the output of the process.
          */
         public static final HttpMethod GET = new HttpMethod("GET");
     
         /**
    -     * The HEAD method is identical to GET except that the server MUST NOT return a message-body in
    -     * the response.
    +     * The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.
          */
         public static final HttpMethod HEAD = new HttpMethod("HEAD");
     
         /**
    -     * The POST method is used to request that the origin server accept the entity enclosed in the
    -     * request as a new subordinate of the resource identified by the Request-URI in the
    -     * Request-Line.
    +     * The POST method is used to request that the origin server accept the entity enclosed in the request as a new
    +     * subordinate of the resource identified by the Request-URI in the Request-Line.
          */
         public static final HttpMethod POST = new HttpMethod("POST");
     
    @@ -67,20 +63,17 @@ public class HttpMethod implements Comparable {
         public static final HttpMethod PATCH = new HttpMethod("PATCH");
     
         /**
    -     * The DELETE method requests that the origin server delete the resource identified by the
    -     * Request-URI.
    +     * The DELETE method requests that the origin server delete the resource identified by the Request-URI.
          */
         public static final HttpMethod DELETE = new HttpMethod("DELETE");
     
         /**
    -     * The TRACE method is used to invoke a remote, application-layer loop- back of the request
    -     * message.
    +     * The TRACE method is used to invoke a remote, application-layer loop- back of the request message.
          */
         public static final HttpMethod TRACE = new HttpMethod("TRACE");
     
         /**
    -     * This specification reserves the method name CONNECT for use with a proxy that can
    -     * dynamically switch to being a tunnel
    +     * This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel
          */
         public static final HttpMethod CONNECT = new HttpMethod("CONNECT");
     
    diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java
    index 450eeba11e..f7129a8826 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseDecoder.java
    @@ -102,9 +102,7 @@ public class HttpResponseDecoder extends HttpMessageDecoder {
     
         @Override
         protected HttpMessage createMessage(String[] initialLine) {
    -        return new DefaultHttpResponse(
    -                HttpVersion.valueOf(initialLine[0]),
    -                new HttpResponseStatus(Integer.valueOf(initialLine[1]), initialLine[2]));
    +        return new DefaultHttpResponse(HttpVersion.valueOf(initialLine[0]), new HttpResponseStatus(Integer.valueOf(initialLine[1]), initialLine[2]));
         }
     
         @Override
    diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseStatus.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseStatus.java
    index 5dcc35da19..9d05f80fef 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseStatus.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpResponseStatus.java
    @@ -56,8 +56,7 @@ public class HttpResponseStatus implements Comparable {
         /**
          * 203 Non-Authoritative Information (since HTTP/1.1)
          */
    -    public static final HttpResponseStatus NON_AUTHORITATIVE_INFORMATION =
    -            new HttpResponseStatus(203, "Non-Authoritative Information");
    +    public static final HttpResponseStatus NON_AUTHORITATIVE_INFORMATION = new HttpResponseStatus(203, "Non-Authoritative Information");
     
         /**
          * 204 No Content
    @@ -152,8 +151,7 @@ public class HttpResponseStatus implements Comparable {
         /**
          * 407 Proxy Authentication Required
          */
    -    public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED =
    -            new HttpResponseStatus(407, "Proxy Authentication Required");
    +    public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = new HttpResponseStatus(407, "Proxy Authentication Required");
     
         /**
          * 408 Request Timeout
    @@ -183,8 +181,7 @@ public class HttpResponseStatus implements Comparable {
         /**
          * 413 Request Entity Too Large
          */
    -    public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE =
    -            new HttpResponseStatus(413, "Request Entity Too Large");
    +    public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = new HttpResponseStatus(413, "Request Entity Too Large");
     
         /**
          * 414 Request-URI Too Long
    @@ -194,14 +191,12 @@ public class HttpResponseStatus implements Comparable {
         /**
          * 415 Unsupported Media Type
          */
    -    public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE =
    -            new HttpResponseStatus(415, "Unsupported Media Type");
    +    public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = new HttpResponseStatus(415, "Unsupported Media Type");
     
         /**
          * 416 Requested Range Not Satisfiable
          */
    -    public static final HttpResponseStatus REQUESTED_RANGE_NOT_SATISFIABLE =
    -            new HttpResponseStatus(416, "Requested Range Not Satisfiable");
    +    public static final HttpResponseStatus REQUESTED_RANGE_NOT_SATISFIABLE = new HttpResponseStatus(416, "Requested Range Not Satisfiable");
     
         /**
          * 417 Expectation Failed
    @@ -236,8 +231,7 @@ public class HttpResponseStatus implements Comparable {
         /**
          * 500 Internal Server Error
          */
    -    public static final HttpResponseStatus INTERNAL_SERVER_ERROR =
    -            new HttpResponseStatus(500, "Internal Server Error");
    +    public static final HttpResponseStatus INTERNAL_SERVER_ERROR = new HttpResponseStatus(500, "Internal Server Error");
     
         /**
          * 501 Not Implemented
    @@ -262,14 +256,12 @@ public class HttpResponseStatus implements Comparable {
         /**
          * 505 HTTP Version Not Supported
          */
    -    public static final HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED =
    -            new HttpResponseStatus(505, "HTTP Version Not Supported");
    +    public static final HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED = new HttpResponseStatus(505, "HTTP Version Not Supported");
     
         /**
          * 506 Variant Also Negotiates (RFC2295)
          */
    -    public static final HttpResponseStatus VARIANT_ALSO_NEGOTIATES =
    -            new HttpResponseStatus(506, "Variant Also Negotiates");
    +    public static final HttpResponseStatus VARIANT_ALSO_NEGOTIATES = new HttpResponseStatus(506, "Variant Also Negotiates");
     
         /**
          * 507 Insufficient Storage (WebDAV, RFC4918)
    diff --git a/src/main/java/org/jboss/netty/handler/codec/http/QueryStringDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/QueryStringDecoder.java
    index 21b1d729d6..1e81bbbe77 100644
    --- a/src/main/java/org/jboss/netty/handler/codec/http/QueryStringDecoder.java
    +++ b/src/main/java/org/jboss/netty/handler/codec/http/QueryStringDecoder.java
    @@ -47,10 +47,10 @@ import org.jboss.netty.util.CharsetUtil;
      *
      * 

    HashDOS vulnerability fix

    * - * As a workaround to the HashDOS vulnerability, the decoder - * limits the maximum number of decoded key-value parameter pairs, up to {@literal 1024} by - * default, and you can configure it when you construct the decoder by passing an additional - * integer parameter. + * As a workaround to the HashDOS + * vulnerability, the decoder limits the maximum number of decoded key-value + * parameter pairs, up to {@literal 1024} by default, and you can configure it + * when you construct the decoder by passing an additional integer parameter. * * @see QueryStringEncoder * diff --git a/src/main/java/org/jboss/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java b/src/main/java/org/jboss/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java index 30826d90f9..4284b4956d 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/multipart/HttpPostRequestDecoder.java @@ -461,8 +461,7 @@ public class HttpPostRequestDecoder { } else if (read == '&') { // special empty FIELD currentStatus = MultiPartStatus.DISPOSITION; ampersandpos = currentpos - 1; - String key = decodeAttribute( - undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset); + String key = decodeAttribute(undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset); currentAttribute = factory.createAttribute(request, key); currentAttribute.setValue(""); // empty addHttpData(currentAttribute); @@ -588,8 +587,7 @@ public class HttpPostRequestDecoder { } else if (read == '&') { // special empty FIELD currentStatus = MultiPartStatus.DISPOSITION; ampersandpos = currentpos - 1; - String key = decodeAttribute( - undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset); + String key = decodeAttribute(undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset); currentAttribute = factory.createAttribute(request, key); currentAttribute.setValue(""); // empty addHttpData(currentAttribute); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java index b4a9f1574c..90c818572e 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/ContinuationWebSocketFrame.java @@ -20,8 +20,8 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.util.CharsetUtil; /** - * Web Socket continuation frame containing continuation text or binary data. This is used for - * fragmented messages where the contents of a messages is contained more than 1 frame. + * Web Socket continuation frame containing continuation text or binary data. This is used for fragmented messages where + * the contents of a messages is contained more than 1 frame. */ public class ContinuationWebSocketFrame extends WebSocketFrame { @@ -35,8 +35,7 @@ public class ContinuationWebSocketFrame extends WebSocketFrame { } /** - * Creates a new continuation frame with the specified binary data. The final fragment flag is - * set to true. + * Creates a new continuation frame with the specified binary data. The final fragment flag is set to true. * * @param binaryData * the content of the frame. @@ -73,8 +72,7 @@ public class ContinuationWebSocketFrame extends WebSocketFrame { * @param aggregatedText * Aggregated text set by decoder on the final continuation frame of a fragmented text message */ - public ContinuationWebSocketFrame( - boolean finalFragment, int rsv, ChannelBuffer binaryData, String aggregatedText) { + public ContinuationWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData, String aggregatedText) { setFinalFragment(finalFragment); setRsv(rsv); setBinaryData(binaryData); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Exception.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Exception.java index 67c2de53ad..3404c76156 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Exception.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Exception.java @@ -18,20 +18,19 @@ * * Copyright (c) 2008-2009 Bjoern Hoehrmann * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or substantial portions + * of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ package org.jboss.netty.handler.codec.http.websocketx; diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Output.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Output.java index f753a755f9..769d5ad370 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Output.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/UTF8Output.java @@ -18,20 +18,19 @@ * * Copyright (c) 2008-2009 Bjoern Hoehrmann * - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software - * and associated documentation files (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, publish, distribute, - * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included in all copies or - * substantial portions of the Software. + * The above copyright notice and this permission notice shall be included in all copies or substantial portions + * of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING - * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. */ package org.jboss.netty.handler.codec.http.websocketx; @@ -42,23 +41,20 @@ final class UTF8Output { private static final int UTF8_ACCEPT = 0; private static final int UTF8_REJECT = 12; - private static final byte[] TYPES = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, - 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6, 6, 5, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8 }; + private static final byte[] TYPES = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, + 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; - private static final byte[] STATES = { 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, - 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, - 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 36, - 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12 }; + private static final byte[] STATES = { 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 24, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12 }; private int state = UTF8_ACCEPT; private int codep; diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java index 105b4a722e..29bae6efb0 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketClientHandshakerFactory.java @@ -27,8 +27,8 @@ public class WebSocketClientHandshakerFactory { * Instances a new handshaker * * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". - * Subsequent web socket frames will be sent to this URL. + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. * @param version * Version of web socket specification to use to connect to the server * @param subprotocol @@ -48,8 +48,8 @@ public class WebSocketClientHandshakerFactory { * Instances a new handshaker * * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". - * Subsequent web socket frames will be sent to this URL. + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. * @param version * Version of web socket specification to use to connect to the server * @param subprotocol @@ -59,24 +59,20 @@ public class WebSocketClientHandshakerFactory { * @param customHeaders * Custom HTTP headers to send during the handshake * @param maxFramePayloadLength - * Maximum allowable frame payload length. Setting this value to your application's - * requirement may reduce denial of service attacks using long data frames. + * Maximum allowable frame payload length. Setting this value to your application's requirement may + * reduce denial of service attacks using long data frames. + * @throws WebSocketHandshakeException */ - public WebSocketClientHandshaker newHandshaker( - URI webSocketURL, WebSocketVersion version, String subprotocol, - boolean allowExtensions, Map customHeaders, long maxFramePayloadLength) - throws WebSocketHandshakeException { + public WebSocketClientHandshaker newHandshaker(URI webSocketURL, WebSocketVersion version, String subprotocol, + boolean allowExtensions, Map customHeaders, long maxFramePayloadLength) throws WebSocketHandshakeException { if (version == WebSocketVersion.V13) { - return new WebSocketClientHandshaker13( - webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength); + return new WebSocketClientHandshaker13(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength); } if (version == WebSocketVersion.V08) { - return new WebSocketClientHandshaker08( - webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength); + return new WebSocketClientHandshaker08(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength); } if (version == WebSocketVersion.V00) { - return new WebSocketClientHandshaker00( - webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength); + return new WebSocketClientHandshaker00(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength); } throw new WebSocketHandshakeException("Protocol version " + version.toString() + " not supported."); diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java index d9746ced36..02de80477a 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshaker00.java @@ -67,8 +67,8 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker { * Constructor specifying the destination web socket location * * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". - * Subsequent web socket frames will be sent to this URL. + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. * @param subprotocols * CSV of supported protocols * @param maxFramePayloadLength diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java index 2c512c1004..f7021f2817 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/WebSocketServerHandshakerFactory.java @@ -52,15 +52,15 @@ public class WebSocketServerHandshakerFactory { * Constructor * * @param webSocketURL - * URL for web socket communications. e.g "ws://myhost.com/mypath". - * Subsequent web socket frames will be sent to this URL. + * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be + * sent to this URL. * @param subprotocols * CSV of supported protocols. Null if sub protocols not supported. * @param allowExtensions * Allow extensions to be used in the reserved bits of the web socket frame * @param maxFramePayloadLength - * Maximum allowable frame payload length. Setting this value to your application's - * requirement may reduce denial of service attacks using long data frames. + * Maximum allowable frame payload length. Setting this value to your application's requirement may + * reduce denial of service attacks using long data frames. */ public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions, long maxFramePayloadLength) { @@ -73,8 +73,8 @@ public class WebSocketServerHandshakerFactory { /** * Instances a new handshaker * - * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web - * socket version is not supported. + * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web socket version is not + * supported. */ public WebSocketServerHandshaker newHandshaker(HttpRequest req) { @@ -82,19 +82,16 @@ public class WebSocketServerHandshakerFactory { if (version != null) { if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) { // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification). - return new WebSocketServerHandshaker13( - webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength); + return new WebSocketServerHandshaker13(webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength); } else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) { // Version 8 of the wire protocol - version 10 of the draft hybi specification. - return new WebSocketServerHandshaker08( - webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength); + return new WebSocketServerHandshaker08(webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength); } else { return null; } } else { // Assume version 00 where version header was not specified - return new WebSocketServerHandshaker00( - webSocketURL, subprotocols, maxFramePayloadLength); + return new WebSocketServerHandshaker00(webSocketURL, subprotocols, maxFramePayloadLength); } } diff --git a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/package-info.java b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/package-info.java index 8806b0294e..6f1372d4bf 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/websocketx/package-info.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/websocketx/package-info.java @@ -21,10 +21,9 @@ * This package supports different web socket specification versions (hence the X suffix). * The specification current supported are: * *

    *

    diff --git a/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java b/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java index 4901666607..e63fcb2d59 100644 --- a/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingDecoder.java @@ -42,15 +42,12 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder { /** * Create a new instance of {@link CompatibleMarshallingDecoder}. * - * @param provider - * the {@link UnmarshallerProvider} which is used to obtain the {@link Unmarshaller} - * for the {@link Channel} - * @param maxObjectSize - * the maximal size (in bytes) of the {@link Object} to unmarshal. Once the size is - * exceeded the {@link Channel} will get closed. Use a a maxObjectSize of - * {@link Integer#MAX_VALUE} to disable this. You should only do this if you are sure - * that the received Objects will never be big and the sending side are trusted, as - * this opens the possibility for a DOS-Attack due an {@link OutOfMemoryError}. + * @param provider the {@link UnmarshallerProvider} which is used to obtain the {@link Unmarshaller} for the {@link Channel} + * @param maxObjectSize the maximal size (in bytes) of the {@link Object} to unmarshal. Once the size is exceeded + * the {@link Channel} will get closed. Use a a maxObjectSize of {@link Integer#MAX_VALUE} to disable this. + * You should only do this if you are sure that the received Objects will never be big and the + * sending side are trusted, as this opens the possibility for a DOS-Attack due an {@link OutOfMemoryError}. + * */ public CompatibleMarshallingDecoder(UnmarshallerProvider provider, int maxObjectSize) { this.provider = provider; @@ -58,8 +55,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder { } @Override - protected Object decode( - ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, VoidEnum state) throws Exception { + protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, VoidEnum state) throws Exception { Unmarshaller unmarshaller = provider.getUnmarshaller(ctx); ByteInput input = new ChannelBufferByteInput(buffer); if (maxObjectSize != Integer.MAX_VALUE) { diff --git a/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingEncoder.java b/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingEncoder.java index bbfa687604..7592190f87 100644 --- a/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/marshalling/CompatibleMarshallingEncoder.java @@ -50,8 +50,7 @@ public class CompatibleMarshallingEncoder extends OneToOneEncoder { @Override protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { Marshaller marshaller = provider.getMarshaller(ctx); - ChannelBufferByteOutput output = - new ChannelBufferByteOutput(ctx.getChannel().getConfig().getBufferFactory(), 256); + ChannelBufferByteOutput output = new ChannelBufferByteOutput(ctx.getChannel().getConfig().getBufferFactory(), 256); marshaller.start(output); marshaller.writeObject(msg); marshaller.finish(); @@ -59,4 +58,5 @@ public class CompatibleMarshallingEncoder extends OneToOneEncoder { return output.getBuffer(); } + } diff --git a/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingDecoder.java b/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingDecoder.java index f4a55a39f8..6d8976e7bf 100644 --- a/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingDecoder.java @@ -27,8 +27,7 @@ import org.jboss.netty.handler.codec.frame.TooLongFrameException; /** * Decoder which MUST be used with {@link MarshallingEncoder}. * - * A {@link LengthFieldBasedFrameDecoder} which use an {@link Unmarshaller} to read the Object out - * of the {@link ChannelBuffer}. + * A {@link LengthFieldBasedFrameDecoder} which use an {@link Unmarshaller} to read the Object out of the {@link ChannelBuffer}. * */ public class MarshallingDecoder extends LengthFieldBasedFrameDecoder { @@ -78,8 +77,8 @@ public class MarshallingDecoder extends LengthFieldBasedFrameDecoder { unmarshaller.finish(); return obj; } finally { - // Call close in a finally block as the ReplayingDecoder will throw an Error if not - // enough bytes are readable. This helps to be sure that we do not leak resource + // Call close in a finally block as the ReplayingDecoder will throw an Error if not enough bytes are + // readable. This helps to be sure that we do not leak resource unmarshaller.close(); } } diff --git a/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingEncoder.java b/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingEncoder.java index 8b7550d296..ffdf9393b1 100644 --- a/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/marshalling/MarshallingEncoder.java @@ -75,8 +75,7 @@ public class MarshallingEncoder extends OneToOneEncoder { @Override protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { Marshaller marshaller = provider.getMarshaller(ctx); - ChannelBufferByteOutput output = new ChannelBufferByteOutput( - ctx.getChannel().getConfig().getBufferFactory(), estimatedLength); + ChannelBufferByteOutput output = new ChannelBufferByteOutput(ctx.getChannel().getConfig().getBufferFactory(), estimatedLength); output.getBuffer().writeBytes(LENGTH_PLACEHOLDER); marshaller.start(output); marshaller.writeObject(msg); diff --git a/src/main/java/org/jboss/netty/handler/codec/replay/ReplayingDecoder.java b/src/main/java/org/jboss/netty/handler/codec/replay/ReplayingDecoder.java index 8a7ee1f726..f88e5a4027 100644 --- a/src/main/java/org/jboss/netty/handler/codec/replay/ReplayingDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/replay/ReplayingDecoder.java @@ -389,9 +389,8 @@ public abstract class ReplayingDecoder> } /** - * Calls {@link #decode(ChannelHandlerContext, Channel, ChannelBuffer, Enum)}. This method - * should be never used by {@link ReplayingDecoder} itself. But to be safe we should handle it - * anyway + * Calls {@link #decode(ChannelHandlerContext, Channel, ChannelBuffer, Enum)}. This method should be never used by {@link ReplayingDecoder} itself. + * But to be safe we should handle it anyway */ @Override protected final Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { @@ -521,9 +520,7 @@ public abstract class ReplayingDecoder> } } - private void callDecode( - ChannelHandlerContext context, Channel channel, - ChannelBuffer input, ChannelBuffer replayableInput, SocketAddress remoteAddress) throws Exception { + private void callDecode(ChannelHandlerContext context, Channel channel, ChannelBuffer input, ChannelBuffer replayableInput, SocketAddress remoteAddress) throws Exception { while (input.readable()) { int oldReaderIndex = checkpoint = input.readerIndex(); Object result = null; diff --git a/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspMethods.java b/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspMethods.java index 1470d4807b..39fd549d08 100644 --- a/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspMethods.java +++ b/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspMethods.java @@ -27,11 +27,10 @@ import org.jboss.netty.handler.codec.http.HttpMethod; public final class RtspMethods { /** - * The OPTIONS method represents a request for information about the communication options - * available on the request/response chain identified by the Request-URI. This method allows - * the client to determine the options and/or requirements associated with a resource, or the - * capabilities of a server, without implying a resource action or initiating a resource - * retrieval. + * The OPTIONS method represents a request for information about the communication options available on the request/response + * chain identified by the Request-URI. This method allows the client to determine the options and/or requirements + * associated with a resource, or the capabilities of a server, without implying a resource action or initiating a + * resource retrieval. */ public static final HttpMethod OPTIONS = HttpMethod.OPTIONS; diff --git a/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspResponseStatuses.java b/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspResponseStatuses.java index 665ac118f1..d198eeef82 100644 --- a/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspResponseStatuses.java +++ b/src/main/java/org/jboss/netty/handler/codec/rtsp/RtspResponseStatuses.java @@ -107,8 +107,7 @@ public final class RtspResponseStatuses { /** * 407 Proxy Authentication Required */ - public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = - HttpResponseStatus.PROXY_AUTHENTICATION_REQUIRED; + public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = HttpResponseStatus.PROXY_AUTHENTICATION_REQUIRED; /** * 408 Request Timeout diff --git a/src/main/java/org/jboss/netty/handler/codec/serialization/ClassResolvers.java b/src/main/java/org/jboss/netty/handler/codec/serialization/ClassResolvers.java index 8500cd32b1..8fbba7a63d 100644 --- a/src/main/java/org/jboss/netty/handler/codec/serialization/ClassResolvers.java +++ b/src/main/java/org/jboss/netty/handler/codec/serialization/ClassResolvers.java @@ -38,9 +38,7 @@ public final class ClassResolvers { * @return new instance of class resolver */ public static ClassResolver weakCachingResolver(ClassLoader classLoader) { - return new CachingClassResolver( - new ClassLoaderClassResolver(defaultClassLoader(classLoader)), - new WeakReferenceMap>(new HashMap>>())); + return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new WeakReferenceMap>(new HashMap>>())); } /** @@ -51,9 +49,7 @@ public final class ClassResolvers { * @return new instance of class resolver */ public static ClassResolver softCachingResolver(ClassLoader classLoader) { - return new CachingClassResolver( - new ClassLoaderClassResolver(defaultClassLoader(classLoader)), - new SoftReferenceMap>(new HashMap>>())); + return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new SoftReferenceMap>(new HashMap>>())); } /** @@ -64,9 +60,7 @@ public final class ClassResolvers { * @return new instance of class resolver */ public static ClassResolver weakCachingConcurrentResolver(ClassLoader classLoader) { - return new CachingClassResolver( - new ClassLoaderClassResolver(defaultClassLoader(classLoader)), - new WeakReferenceMap>(new ConcurrentHashMap>>())); + return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new WeakReferenceMap>(new ConcurrentHashMap>>())); } /** @@ -77,9 +71,7 @@ public final class ClassResolvers { * @return new instance of class resolver */ public static ClassResolver softCachingConcurrentResolver(ClassLoader classLoader) { - return new CachingClassResolver( - new ClassLoaderClassResolver(defaultClassLoader(classLoader)), - new SoftReferenceMap>(new ConcurrentHashMap>>())); + return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new SoftReferenceMap>(new ConcurrentHashMap>>())); } static ClassLoader defaultClassLoader(ClassLoader classLoader) { diff --git a/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectDecoder.java b/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectDecoder.java index 8afa62e1e6..6823911935 100644 --- a/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectDecoder.java @@ -74,8 +74,7 @@ public class CompatibleObjectDecoder extends ReplayingDecodertrue if the {@link ChannelEventRunnable} should get handled by the {@link Executor} - * - */ - boolean filter(ChannelEventRunnable event); -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.handler.execution; + +import java.util.concurrent.Executor; + +public interface ChannelEventRunnableFilter { + + /** + * Return true if the {@link ChannelEventRunnable} should get handled by the {@link Executor} + * + */ + boolean filter(ChannelEventRunnable event); +} diff --git a/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnable.java b/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnable.java index caac49aa31..ba8433cdb1 100644 --- a/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnable.java +++ b/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnable.java @@ -32,16 +32,15 @@ public class ChannelUpstreamEventRunnable extends ChannelEventRunnable { * Creates a {@link Runnable} which sends the specified {@link ChannelEvent} * upstream via the specified {@link ChannelHandlerContext}. */ - public ChannelUpstreamEventRunnable(ChannelHandlerContext ctx, ChannelEvent e, Executor executor) { - super(ctx, e, executor); + public ChannelUpstreamEventRunnable(ChannelHandlerContext ctx, ChannelEvent e) { + super(ctx, e); } /** * Sends the event upstream. */ - @Override - protected void doRun() { + public void run() { ctx.sendUpstream(e); } } diff --git a/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnableFilter.java b/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnableFilter.java index 49655a44c6..4d1f9bd0c3 100644 --- a/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnableFilter.java +++ b/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnableFilter.java @@ -1,25 +1,25 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.handler.execution; - -/** - * {@link ChannelEventRunnableFilter} which matches {@link ChannelDownstreamEventRunnable} - */ -public class ChannelUpstreamEventRunnableFilter implements ChannelEventRunnableFilter { - public boolean filter(ChannelEventRunnable event) { - return event instanceof ChannelDownstreamEventRunnable; - } -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.handler.execution; + +/** + * {@link ChannelEventRunnableFilter} which matches {@link ChannelDownstreamEventRunnable} + */ +public class ChannelUpstreamEventRunnableFilter implements ChannelEventRunnableFilter { + public boolean filter(ChannelEventRunnable event) { + return event instanceof ChannelDownstreamEventRunnable; + } +} diff --git a/src/main/java/org/jboss/netty/handler/execution/ExecutionHandler.java b/src/main/java/org/jboss/netty/handler/execution/ExecutionHandler.java index dde16c540d..d65a05e4ef 100644 --- a/src/main/java/org/jboss/netty/handler/execution/ExecutionHandler.java +++ b/src/main/java/org/jboss/netty/handler/execution/ExecutionHandler.java @@ -169,7 +169,7 @@ public class ExecutionHandler implements ChannelUpstreamHandler, ChannelDownstre public void handleUpstream( ChannelHandlerContext context, ChannelEvent e) throws Exception { if (handleUpstream) { - executor.execute(new ChannelUpstreamEventRunnable(context, e, executor)); + executor.execute(new ChannelUpstreamEventRunnable(context, e)); } else { context.sendUpstream(e); } @@ -180,7 +180,7 @@ public class ExecutionHandler implements ChannelUpstreamHandler, ChannelDownstre // check if the read was suspend if (!handleReadSuspend(ctx, e)) { if (handleDownstream) { - executor.execute(new ChannelDownstreamEventRunnable(ctx, e, executor)); + executor.execute(new ChannelDownstreamEventRunnable(ctx, e)); } else { ctx.sendDownstream(e); } diff --git a/src/main/java/org/jboss/netty/handler/execution/MemoryAwareThreadPoolExecutor.java b/src/main/java/org/jboss/netty/handler/execution/MemoryAwareThreadPoolExecutor.java index 1431438054..13adf11d1e 100644 --- a/src/main/java/org/jboss/netty/handler/execution/MemoryAwareThreadPoolExecutor.java +++ b/src/main/java/org/jboss/netty/handler/execution/MemoryAwareThreadPoolExecutor.java @@ -182,9 +182,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { int corePoolSize, long maxChannelMemorySize, long maxTotalMemorySize, long keepAliveTime, TimeUnit unit) { - this( - corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit, - Executors.defaultThreadFactory()); + this(corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit, Executors.defaultThreadFactory()); } /** @@ -203,9 +201,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { int corePoolSize, long maxChannelMemorySize, long maxTotalMemorySize, long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) { - this( - corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit, - new DefaultObjectSizeEstimator(), threadFactory); + this(corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit, new DefaultObjectSizeEstimator(), threadFactory); } /** @@ -281,13 +277,11 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { } /** - * See {@link ThreadPoolExecutor#shutdownNow()} for how it handles the shutdown. - * If true is given to this method it also notifies all {@link ChannelFuture}'s + * See {@link ThreadPoolExecutor#shutdownNow()} for how it handles the shutdown. If true is given to this method it also notifies all {@link ChannelFuture}'s * of the not executed {@link ChannelEventRunnable}'s. * *

    - * Be aware that if you call this with false you will need to handle the - * notification of the {@link ChannelFuture}'s by your self. So only use this if you + * Be aware that if you call this with false you will need to handle the notification of the {@link ChannelFuture}'s by your self. So only use this if you * really have a use-case for it. *

    * @@ -401,13 +395,11 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { } /** - * If set to false no queued {@link ChannelEventRunnable}'s {@link ChannelFuture} - * will get notified once {@link #shutdownNow()} is called. If set to true every - * queued {@link ChannelEventRunnable} will get marked as failed via {@link ChannelFuture#setFailure(Throwable)}. + * If set to false no queued {@link ChannelEventRunnable}'s {@link ChannelFuture} will get notified once {@link #shutdownNow()} is called. + * If set to true every queued {@link ChannelEventRunnable} will get marked as failed via {@link ChannelFuture#setFailure(Throwable)}. * *

    - * Please only set this to false if you want to handle the notification by yourself - * and know what you are doing. Default is true. + * Please only set this to false if you want to handle the notification by yourself and know what you are doing. Default is true. *

    */ public void setNotifyChannelFuturesOnShutdown(boolean notifyOnShutdown) { @@ -415,8 +407,8 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { } /** - * Returns if the {@link ChannelFuture}'s of the {@link ChannelEventRunnable}'s should be - * notified about the shutdown of this {@link MemoryAwareThreadPoolExecutor}. + * Returns if the {@link ChannelFuture}'s of the {@link ChannelEventRunnable}'s should be notified about the shutdown of this {@link MemoryAwareThreadPoolExecutor}. + * */ public boolean getNotifyChannelFuturesOnShutdown() { return notifyOnShutdown; @@ -532,9 +524,8 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { //System.out.println("READABLE"); ChannelHandlerContext ctx = eventTask.getContext(); if (ctx.getHandler() instanceof ExecutionHandler) { - // check if the attachment was set as this means that we suspend the channel - // from reads. This only works when this pool is used with ExecutionHandler - // but I guess thats good enough for us. + // check if the attachment was set as this means that we suspend the channel from reads. This only works when + // this pool is used with ExecutionHandler but I guess thats good enough for us. // // See #215 if (ctx.getAttachment() != null) { diff --git a/src/main/java/org/jboss/netty/handler/execution/OrderedDownstreamThreadPoolExecutor.java b/src/main/java/org/jboss/netty/handler/execution/OrderedDownstreamThreadPoolExecutor.java index b91e6f566f..a6b75f8e91 100644 --- a/src/main/java/org/jboss/netty/handler/execution/OrderedDownstreamThreadPoolExecutor.java +++ b/src/main/java/org/jboss/netty/handler/execution/OrderedDownstreamThreadPoolExecutor.java @@ -28,13 +28,13 @@ import org.jboss.netty.channel.ChannelFutureListener; import org.jboss.netty.util.ObjectSizeEstimator; /** - * {@link Executor} which should be used for downstream {@link ChannelEvent}'s. This implementation - * will take care of preserve the order of the events in a {@link Channel}. If you don't need to - * preserve the order just use one of the {@link Executor} implementations provided by the static - * methods of {@link Executors}. + * {@link Executor} which should be used for downstream {@link ChannelEvent}'s. This implementation will take care of preserve the order of the events in a {@link Channel}. + * If you don't need to preserve the order just use one of the {@link Executor} implementations provided by the static methods of {@link Executors}. *
    *
    + * * For more informations about how the order is preserved see {@link OrderedMemoryAwareThreadPoolExecutor} + * */ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwareThreadPoolExecutor { @@ -83,8 +83,7 @@ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwar } /** - * Throws {@link UnsupportedOperationException} as there is not support for limit the memory - * size in this implementation + * Throws {@link UnsupportedOperationException} as there is not support for limit the memory size in this implementation */ @Override public void setObjectSizeEstimator(ObjectSizeEstimator objectSizeEstimator) { @@ -100,8 +99,7 @@ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwar } /** - * Throws {@link UnsupportedOperationException} as there is not support for limit the memory - * size in this implementation + * Throws {@link UnsupportedOperationException} as there is not support for limit the memory size in this implementation */ @Override public void setMaxChannelMemorySize(long maxChannelMemorySize) { @@ -117,8 +115,7 @@ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwar } /** - * Throws {@link UnsupportedOperationException} as there is not support for limit the memory - * size in this implementation + * Throws {@link UnsupportedOperationException} as there is not support for limit the memory size in this implementation */ @Override public void setMaxTotalMemorySize(long maxTotalMemorySize) { diff --git a/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java b/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java index 345bd9121b..37f2932112 100644 --- a/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java +++ b/src/main/java/org/jboss/netty/handler/execution/OrderedMemoryAwareThreadPoolExecutor.java @@ -125,7 +125,7 @@ import org.jboss.netty.util.internal.QueueFactory; *
    * * If the expected maximum number of keys is small and deterministic, you could - * use a weak key map such as ConcurrentWeakHashMap + * use a weak key map such as ConcurrentWeakHashMap * or synchronized {@link WeakHashMap} instead of managing the life cycle of the * keys by yourself. * diff --git a/src/main/java/org/jboss/netty/handler/ipfilter/IpFilterRuleHandler.java b/src/main/java/org/jboss/netty/handler/ipfilter/IpFilterRuleHandler.java index 5dd813ad73..38e68374fb 100644 --- a/src/main/java/org/jboss/netty/handler/ipfilter/IpFilterRuleHandler.java +++ b/src/main/java/org/jboss/netty/handler/ipfilter/IpFilterRuleHandler.java @@ -30,8 +30,7 @@ import org.jboss.netty.channel.ChannelHandlerContext; * Implementation of Filter of IP based on ALLOW and DENY rules.
    *

    * This implementation could be changed by implementing a new {@link IpFilterRule} than default - * {@link IpV4SubnetFilterRule} (IPV4 support only), {@link IpSubnetFilterRule} (IPV4 and IPV6 support) - * or {@link IpFilterRule} (IP and host name string pattern support) .
    + * {@link IpV4SubnetFilterRule} (IPV4 support only), {@link IpSubnetFilterRule} (IPV4 and IPV6 support) or {@link IpFilterRule} (IP and host name string pattern support) .
    *
    * The check is done by going from step to step in the underlying array of IpFilterRule.
    * Each {@link IpFilterRule} answers to the method accept if the {@link InetAddress} is accepted or not, diff --git a/src/main/java/org/jboss/netty/handler/ipfilter/package-info.java b/src/main/java/org/jboss/netty/handler/ipfilter/package-info.java index 4ac2390535..e52fad7309 100644 --- a/src/main/java/org/jboss/netty/handler/ipfilter/package-info.java +++ b/src/main/java/org/jboss/netty/handler/ipfilter/package-info.java @@ -18,20 +18,17 @@ * Implementation of a Ip based Filter handlers.
    *

    *

    The main goal of this package is to allow to filter connections based on IP rules. - * The main interface is {@link org.jboss.netty.handler.ipfilter.IpFilteringHandler} which - * all filters will extend.

    + * The main interface is {@link org.jboss.netty.handler.ipfilter.IpFilteringHandler} which all filters will extend.

    * *

    Two IP filtering are proposed:
    *

      - *
    • {@link org.jboss.netty.handler.ipfilter.OneIpFilterHandler}: This filter proposes to allow - * only one connection by client's IP Address. I.E. this filter will prevent two connections - * from the same client based on its IP address.


    • + *
    • {@link org.jboss.netty.handler.ipfilter.OneIpFilterHandler}: This filter proposes to allow only one connection by client's IP Address. + * I.E. this filter will prevent two connections from the same client based on its IP address.


    • * - *
    • {@link org.jboss.netty.handler.ipfilter.IpFilterRuleHandler}: This filter proposes to allow - * or block IP range (based on standard notation or on CIDR notation) when the connection is - * running. It relies on another class like IpV4SubnetFilterRule (IPV4 support only), - * IpSubnetFilterRule (IPV4 and IPV6 support) or PatternRule (string pattern - * support) which implements those Ip ranges.


    • + *
    • {@link org.jboss.netty.handler.ipfilter.IpFilterRuleHandler}: This filter proposes to allow or block IP range (based on standard notation + * or on CIDR notation) when the connection is running. It relies on another class like + * IpV4SubnetFilterRule (IPV4 support only), IpSubnetFilterRule (IPV4 and IPV6 support) or PatternRule (string pattern support) + * which implements those Ip ranges.


    • * *

    * @@ -45,32 +42,27 @@ * this method is already implemented.
    *
    * - *
  • handleRefusedChannel method is executed when the accept method filters (blocks, so returning - * false) the new connection. This method allows you to implement specific actions to be taken - * before the channel is closed. After this method is called, the channel is immediately closed.

  • - * - * So if you want to send back a message to the client, don't forget to return a respectful - * ChannelFuture, otherwise the message could be missed since the channel will be closed immediately - * after this call and the waiting on this channelFuture (at least with respect of asynchronous - * operations).

    - * Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener} - * or returns null if no listener has been set. + *
  • handleRefusedChannel method is executed when the accept method filters (blocks, so returning false) + * the new connection. This method allows you to implement specific actions to be taken before the channel is + * closed. After this method is called, the channel is immediately closed.

  • + * So if you want to send back a message to the client, don't forget to return a respectful ChannelFuture, + * otherwise the message could be missed since the channel will be closed immediately after this + * call and the waiting on this channelFuture (at least with respect of asynchronous operations).

    + * Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener} or returns null if no listener has been set. *

    * *
  • continues is called when any event appears after CONNECTED event and only for * blocked channels.

  • * It should return True if this new event has to go to next handlers * in the pipeline if any, and False (default) if no events has to be passed to the next - * handlers when a channel is blocked. This is intend to prevent any unnecessary action since the - * connection is refused.
    + * handlers when a channel is blocked. This is intend to prevent any unnecessary action since the connection is refused.
    * However, you could change its behavior for instance because you don't want that any event * will be blocked by this filter by returning always true or according to some events.
    * Note that OPENED and BOUND events are still passed to the next entry in the pipeline since * those events come out before the CONNECTED event, so there is no possibility to filter those two events * before the CONNECTED event shows up. Therefore, you might want to let CLOSED and UNBOUND be passed * to the next entry in the pipeline.

    - * Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener} - * or returns false if no listener has been set. + * Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener} or returns false if no listener has been set. *

    * *
  • Finally handleUpstream traps the CONNECTED and DISCONNECTED events.

  • @@ -78,8 +70,7 @@ * then any new events on this channel will be blocked.
    * However, you could change its behavior for instance because you don't want that all events * will be blocked by this filter by testing the result of isBlocked, and if so, - * calling ctx.sendUpstream(e); after calling the super method or by changing the - * continues method.

    + * calling ctx.sendUpstream(e); after calling the super method or by changing the continues method.

    *



    * diff --git a/src/main/java/org/jboss/netty/handler/queue/BlockingReadHandler.java b/src/main/java/org/jboss/netty/handler/queue/BlockingReadHandler.java index 9fd5f57dc2..d206394bdb 100644 --- a/src/main/java/org/jboss/netty/handler/queue/BlockingReadHandler.java +++ b/src/main/java/org/jboss/netty/handler/queue/BlockingReadHandler.java @@ -219,8 +219,7 @@ public class BlockingReadHandler extends SimpleChannelUpstreamHandler { * @throws InterruptedException * if the operation has been interrupted */ - public ChannelEvent readEvent( - long timeout, TimeUnit unit) throws InterruptedException, BlockingReadTimeoutException { + public ChannelEvent readEvent(long timeout, TimeUnit unit) throws InterruptedException, BlockingReadTimeoutException { detectDeadLock(); if (isClosed()) { if (getQueue().isEmpty()) { diff --git a/src/main/java/org/jboss/netty/handler/queue/BufferedWriteHandler.java b/src/main/java/org/jboss/netty/handler/queue/BufferedWriteHandler.java index d9b042efc5..bae13234f2 100644 --- a/src/main/java/org/jboss/netty/handler/queue/BufferedWriteHandler.java +++ b/src/main/java/org/jboss/netty/handler/queue/BufferedWriteHandler.java @@ -142,8 +142,7 @@ import org.jboss.netty.util.internal.QueueFactory; * } * * {@literal @Override} - * public void channelInterestChanged( - * {@link ChannelHandlerContext} ctx, {@link ChannelStateEvent} e) throws Exception { + * public void channelInterestChanged({@link ChannelHandlerContext} ctx, {@link ChannelStateEvent} e) throws Exception { * if (e.getChannel().isWritable()) { * flush(); * } @@ -356,8 +355,7 @@ public class BufferedWriteHandler extends SimpleChannelHandler implements LifeCy } /** - * Fail all buffered writes that are left. See - * #308 for more details */ @Override public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { @@ -398,8 +396,7 @@ public class BufferedWriteHandler extends SimpleChannelHandler implements LifeCy } /** - * Fail all buffered writes that are left. - * See #308 for more details */ public void afterRemove(ChannelHandlerContext ctx) throws Exception { Throwable cause = null; diff --git a/src/main/java/org/jboss/netty/handler/ssl/SslHandler.java b/src/main/java/org/jboss/netty/handler/ssl/SslHandler.java index a5c59f84db..a2748e4d8a 100644 --- a/src/main/java/org/jboss/netty/handler/ssl/SslHandler.java +++ b/src/main/java/org/jboss/netty/handler/ssl/SslHandler.java @@ -70,10 +70,9 @@ import org.jboss.netty.util.internal.QueueFactory; *

    Handshake

    *

    * If {@link #isIssueHandshake()} is {@code false} - * (default) you will need to take care of calling {@link #handshake()} by your own. In most - * situations were {@link SslHandler} is used in 'client mode' you want to issue a handshake once - * the connection was established. if {@link #setIssueHandshake(boolean)} is set to true - * you don't need to worry about this as the {@link SslHandler} will take care of it. + * (default) you will need to take care of calling {@link #handshake()} by your own. In most situations were {@link SslHandler} is used in 'client mode' + * you want to issue a handshake once the connection was established. if {@link #setIssueHandshake(boolean)} is set to true you don't need to + * worry about this as the {@link SslHandler} will take care of it. *

    * *

    Renegotiation

    @@ -92,8 +91,7 @@ import org.jboss.netty.util.internal.QueueFactory; * * *

    Closing the session

    @@ -871,8 +869,7 @@ public class SslHandler extends FrameDecoder if (result.bytesProduced() > 0) { outNetBuf.flip(); - ChannelBuffer msg = - ctx.getChannel().getConfig().getBufferFactory().getBuffer(outNetBuf.remaining()); + ChannelBuffer msg = ctx.getChannel().getConfig().getBufferFactory().getBuffer(outNetBuf.remaining()); // Transfer the bytes to the new ChannelBuffer using some safe method that will also @@ -942,8 +939,7 @@ public class SslHandler extends FrameDecoder } private ChannelBuffer unwrap( - ChannelHandlerContext ctx, Channel channel, - ChannelBuffer buffer, int offset, int length) throws SSLException { + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, int offset, int length) throws SSLException { ByteBuffer inNetBuf = buffer.toByteBuffer(offset, length); ByteBuffer outAppBuf = bufferPool.acquireBuffer(); @@ -1279,8 +1275,7 @@ public class SslHandler extends FrameDecoder @Override public void channelConnected(final ChannelHandlerContext ctx, final ChannelStateEvent e) throws Exception { if (issueHandshake) { - // issue and handshake and add a listener to it which will fire an exception event if - // an exception was thrown while doing the handshake + // issue and handshake and add a listener to it which will fire an exception event if an exception was thrown while doing the handshake handshake().addListener(new ChannelFutureListener() { public void operationComplete(ChannelFuture future) throws Exception { diff --git a/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java b/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java index 6d78475ad4..3811234585 100644 --- a/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java +++ b/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java @@ -73,8 +73,7 @@ import org.jboss.netty.util.internal.QueueFactory; * @apiviz.landmark * @apiviz.has org.jboss.netty.handler.stream.ChunkedInput oneway - - reads from */ -public class ChunkedWriteHandler - implements ChannelUpstreamHandler, ChannelDownstreamHandler, LifeCycleAwareChannelHandler { +public class ChunkedWriteHandler implements ChannelUpstreamHandler, ChannelDownstreamHandler, LifeCycleAwareChannelHandler { private static final InternalLogger logger = InternalLoggerFactory.getInstance(ChunkedWriteHandler.class); @@ -252,9 +251,8 @@ public class ChunkedWriteHandler this.currentEvent = null; writeFuture = currentEvent.getFuture(); - // Register a listener which will close the input once the write - // is complete. This is needed because the Chunk may have some - // resource bound that can not be closed before its not written + // Register a listener which will close the input once the write is complete. This is needed because the Chunk may have + // some resource bound that can not be closed before its not written // // See https://github.com/netty/netty/issues/303 writeFuture.addListener(new ChannelFutureListener() { diff --git a/src/main/java/org/jboss/netty/handler/traffic/package-info.java b/src/main/java/org/jboss/netty/handler/traffic/package-info.java index 33762355d3..a191f813e8 100644 --- a/src/main/java/org/jboss/netty/handler/traffic/package-info.java +++ b/src/main/java/org/jboss/netty/handler/traffic/package-info.java @@ -25,16 +25,14 @@ * *

    Two classes implement this behavior:
    *

      - *
    • {@link org.jboss.netty.handler.traffic.TrafficCounter}: this class implements the counters - * needed by the handlers. It can be accessed to get some extra information like the read or - * write bytes since last check, the read and write bandwidth from last check...


    • + *
    • {@link org.jboss.netty.handler.traffic.TrafficCounter}: this class implements the counters needed by the handlers. + * It can be accessed to get some extra information like the read or write bytes since last check, the read and write + * bandwidth from last check...


    • * - *
    • {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler}: this abstract class - * implements the kernel of the traffic shaping. It could be extended to fit your needs. Two - * classes are proposed as default implementations: see - * {@link org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler} and - * {@link org.jboss.netty.handler.traffic.GlobalTrafficShapingHandler} respectively for - * Channel traffic shaping and Global traffic shaping.


    • + *
    • {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler}: this abstract class implements the kernel + * of the traffic shaping. It could be extended to fit your needs. Two classes are proposed as default + * implementations: see {@link org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler} and see {@link org.jboss.netty.handler.traffic.GlobalTrafficShapingHandler} + * respectively for Channel traffic shaping and Global traffic shaping.


    • * * The insertion in the pipeline of one of those handlers can be wherever you want, but * it must be placed before any {@link MemoryAwareThreadPoolExecutor} @@ -64,16 +62,14 @@ * [Global or per Channel] [Write or Read] Limitation in byte/s.
      * A value of 0 * stands for no limitation, so the traffic shaping is deactivate (on what you specified).
      - * You can either change those values with the method configure in - * {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler}.
      + * You can either change those values with the method configure in {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler}.
      *
      * *
    • To activate or deactivate the statistics, you can adjust the delay to a low (suggested not less than 200ms * for efficiency reasons) or a high value (let say 24H in millisecond is huge enough to not get the problem) * or even using 0 which means no computation will be done.

    • * If you want to do anything with this statistics, just override the doAccounting method.
      - * This interval can be changed either from the method configure in - * {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler} + * This interval can be changed either from the method configure in {@link org.jboss.netty.handler.traffic.AbstractTrafficShapingHandler} * or directly using the method configure of {@link org.jboss.netty.handler.traffic.TrafficCounter}.

      * *



    @@ -85,9 +81,8 @@ * pipeline.addLast("XXXXX_TRAFFIC_SHAPING", myHandler);
    * ...
    * pipeline.addLast("MemoryExecutor",new ExecutionHandler(memoryAwareThreadPoolExecutor));

    - *

    Note that a new {@link org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler} must be - * created for each new channel, but only one {@link org.jboss.netty.handler.traffic.GlobalTrafficShapingHandler} - * must be created for all channels.

    + *

    Note that a new {@link org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler} must be created for each new channel, + * but only one {@link org.jboss.netty.handler.traffic.GlobalTrafficShapingHandler} must be created for all channels.

    * *

    Note also that you can create different GlobalTrafficShapingHandler if you want to separate classes of * channels (for instance either from business point of view or from bind address point of view).

    diff --git a/src/main/java/org/jboss/netty/util/internal/DetectionUtil.java b/src/main/java/org/jboss/netty/util/internal/DetectionUtil.java index 0d6e812d6f..8529fcc5e1 100644 --- a/src/main/java/org/jboss/netty/util/internal/DetectionUtil.java +++ b/src/main/java/org/jboss/netty/util/internal/DetectionUtil.java @@ -1,117 +1,117 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.util.internal; - -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.zip.Deflater; - - -/** - * Utility that detects various properties specific to the current runtime - * environment, such as Java version and the availability of the - * {@code sun.misc.Unsafe} object. - * - *
    - * You can disable the use of {@code sun.misc.Unsafe} if you specify - * the System property org.jboss.netty.tryUnsafe with - * value of false. Default is true. - */ -public final class DetectionUtil { - - private static final int JAVA_VERSION = javaVersion0(); - private static final boolean HAS_UNSAFE = hasUnsafe(AtomicInteger.class.getClassLoader()); - private static final boolean IS_WINDOWS; - static { - String os = System.getProperty("os.name").toLowerCase(); - // windows - IS_WINDOWS = os.indexOf("win") >= 0; - } - - /** - * Return true if the JVM is running on Windows - * - */ - public static boolean isWindows() { - return IS_WINDOWS; - } - - public static boolean hasUnsafe() { - return HAS_UNSAFE; - } - - public static int javaVersion() { - return JAVA_VERSION; - } - - private static boolean hasUnsafe(ClassLoader loader) { - boolean useUnsafe = Boolean.valueOf(SystemPropertyUtil.get("org.jboss.netty.tryUnsafe", "true")); - if (!useUnsafe) { - return false; - } - - try { - Class unsafeClazz = Class.forName("sun.misc.Unsafe", true, loader); - return hasUnsafeField(unsafeClazz); - } catch (Exception e) { - // Ignore - } - return false; - } - - private static boolean hasUnsafeField(final Class unsafeClass) throws PrivilegedActionException { - return AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Boolean run() throws Exception { - unsafeClass.getDeclaredField("theUnsafe"); - return true; - } - }); - } - - private static int javaVersion0() { - try { - // Check if its android, if so handle it the same way as java6. - // - // See https://github.com/netty/netty/issues/282 - Class.forName("android.app.Application"); - return 6; - } catch (ClassNotFoundException e) { - //Ignore - } - - try { - Deflater.class.getDeclaredField("SYNC_FLUSH"); - return 7; - } catch (Exception e) { - // Ignore - } - - try { - Double.class.getDeclaredField("MIN_NORMAL"); - return 6; - } catch (Exception e) { - // Ignore - } - - return 5; - } - - private DetectionUtil() { - // only static method supported - } -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.util.internal; + +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.zip.Deflater; + + +/** + * Utility that detects various properties specific to the current runtime + * environment, such as Java version and the availability of the + * {@code sun.misc.Unsafe} object. + * + *
    + * You can disable the use of {@code sun.misc.Unsafe} if you specify + * the System property org.jboss.netty.tryUnsafe with + * value of false. Default is true. + */ +public final class DetectionUtil { + + private static final int JAVA_VERSION = javaVersion0(); + private static final boolean HAS_UNSAFE = hasUnsafe(AtomicInteger.class.getClassLoader()); + private static final boolean IS_WINDOWS; + static { + String os = System.getProperty("os.name").toLowerCase(); + // windows + IS_WINDOWS = os.indexOf("win") >= 0; + } + + /** + * Return true if the JVM is running on Windows + * + */ + public static boolean isWindows() { + return IS_WINDOWS; + } + + public static boolean hasUnsafe() { + return HAS_UNSAFE; + } + + public static int javaVersion() { + return JAVA_VERSION; + } + + private static boolean hasUnsafe(ClassLoader loader) { + boolean useUnsafe = Boolean.valueOf(SystemPropertyUtil.get("org.jboss.netty.tryUnsafe", "true")); + if (!useUnsafe) { + return false; + } + + try { + Class unsafeClazz = Class.forName("sun.misc.Unsafe", true, loader); + return hasUnsafeField(unsafeClazz); + } catch (Exception e) { + // Ignore + } + return false; + } + + private static boolean hasUnsafeField(final Class unsafeClass) throws PrivilegedActionException { + return AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Boolean run() throws Exception { + unsafeClass.getDeclaredField("theUnsafe"); + return true; + } + }); + } + + private static int javaVersion0() { + try { + // Check if its android, if so handle it the same way as java6. + // + // See https://github.com/netty/netty/issues/282 + Class.forName("android.app.Application"); + return 6; + } catch (ClassNotFoundException e) { + //Ignore + } + + try { + Deflater.class.getDeclaredField("SYNC_FLUSH"); + return 7; + } catch (Exception e) { + // Ignore + } + + try { + Double.class.getDeclaredField("MIN_NORMAL"); + return 6; + } catch (Exception e) { + // Ignore + } + + return 5; + } + + private DetectionUtil() { + // only static method supported + } +} diff --git a/src/main/java/org/jboss/netty/util/internal/QueueFactory.java b/src/main/java/org/jboss/netty/util/internal/QueueFactory.java index 6dfe83a39e..8e039620c3 100644 --- a/src/main/java/org/jboss/netty/util/internal/QueueFactory.java +++ b/src/main/java/org/jboss/netty/util/internal/QueueFactory.java @@ -1,102 +1,100 @@ -/* - * Copyright 2012 The Netty Project - * - * The Netty Project licenses this file to you under the Apache License, - * version 2.0 (the "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - */ -package org.jboss.netty.util.internal; - -import java.util.Collection; -import java.util.concurrent.BlockingQueue; - -import org.jboss.netty.logging.InternalLogger; -import org.jboss.netty.logging.InternalLoggerFactory; - -/** - * This factory should be used to create the "optimal" {@link BlockingQueue} - * instance for the running JVM. - */ -public final class QueueFactory { - - private static final boolean useUnsafe = DetectionUtil.hasUnsafe(); - private static final InternalLogger LOGGER = InternalLoggerFactory.getInstance(QueueFactory.class); - - private QueueFactory() { - // only use static methods! - } - - - /** - * Create a new unbound {@link BlockingQueue} - * - * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items - * @return queue the {@link BlockingQueue} implementation - */ - public static BlockingQueue createQueue(Class itemClass) { - // if we run in java >=7 its the best to just use the LinkedTransferQueue which - // comes with java bundled. See #273 - if (DetectionUtil.javaVersion() >= 7) { - return new java.util.concurrent.LinkedTransferQueue(); - } - - try { - if (useUnsafe) { - return new LinkedTransferQueue(); - } - } catch (Throwable t) { - // For whatever reason an exception was thrown while loading the LinkedTransferQueue - // - // This mostly happens because of a custom classloader or security policy that did not - // allow us to access the com.sun.Unmisc class. So just log it and fallback to the old - // LegacyLinkedTransferQueue that works in all cases - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t); - } - } - - return new LegacyLinkedTransferQueue(); - - } - - /** - * Create a new unbound {@link BlockingQueue} - * - * @param collection the collection which should get copied to the newly created {@link BlockingQueue} - * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items - * @return queue the {@link BlockingQueue} implementation - */ - public static BlockingQueue createQueue(Collection collection, Class itemClass) { - // if we run in java >=7 its the best to just use the LinkedTransferQueue which - // comes with java bundled. See #273 - if (DetectionUtil.javaVersion() >= 7) { - return new java.util.concurrent.LinkedTransferQueue(); - } - - try { - if (useUnsafe) { - return new LinkedTransferQueue(collection); - } - } catch (Throwable t) { - // For whatever reason an exception was thrown while loading the LinkedTransferQueue - // - // This mostly happens because of a custom classloader or security policy that did not - // allow us to access the com.sun.Unmisc class. So just log it and fallback to the old - // LegacyLinkedTransferQueue that works in all cases - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t); - } - } - - return new LegacyLinkedTransferQueue(collection); - - } -} +/* + * Copyright 2012 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package org.jboss.netty.util.internal; + +import java.util.Collection; +import java.util.concurrent.BlockingQueue; + +import org.jboss.netty.logging.InternalLogger; +import org.jboss.netty.logging.InternalLoggerFactory; + +/** + * This factory should be used to create the "optimal" {@link BlockingQueue} + * instance for the running JVM. + */ +public final class QueueFactory { + + private static final boolean useUnsafe = DetectionUtil.hasUnsafe(); + private static final InternalLogger LOGGER = InternalLoggerFactory.getInstance(QueueFactory.class); + + private QueueFactory() { + // only use static methods! + } + + + /** + * Create a new unbound {@link BlockingQueue} + * + * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items + * @return queue the {@link BlockingQueue} implementation + */ + public static BlockingQueue createQueue(Class itemClass) { + // if we run in java >=7 its the best to just use the LinkedTransferQueue which + // comes with java bundled. See #273 + if (DetectionUtil.javaVersion() >= 7) { + return new java.util.concurrent.LinkedTransferQueue(); + } + + try { + if (useUnsafe) { + return new LinkedTransferQueue(); + } + } catch (Throwable t) { + // For whatever reason an exception was thrown while loading the LinkedTransferQueue + // + // This mostly happens because of a custom classloader or security policy that did not allow us to access the + // com.sun.Unmisc class. So just log it and fallback to the old LegacyLinkedTransferQueue that works in all cases + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t); + } + } + + return new LegacyLinkedTransferQueue(); + + } + + /** + * Create a new unbound {@link BlockingQueue} + * + * @param collection the collection which should get copied to the newly created {@link BlockingQueue} + * @param itemClass the {@link Class} type which will be used as {@link BlockingQueue} items + * @return queue the {@link BlockingQueue} implementation + */ + public static BlockingQueue createQueue(Collection collection, Class itemClass) { + // if we run in java >=7 its the best to just use the LinkedTransferQueue which + // comes with java bundled. See #273 + if (DetectionUtil.javaVersion() >= 7) { + return new java.util.concurrent.LinkedTransferQueue(); + } + + try { + if (useUnsafe) { + return new LinkedTransferQueue(collection); + } + } catch (Throwable t) { + // For whatever reason an exception was thrown while loading the LinkedTransferQueue + // + // This mostly happens because of a custom classloader or security policy that did not allow us to access the + // com.sun.Unmisc class. So just log it and fallback to the old LegacyLinkedTransferQueue that works in all cases + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Unable to instance LinkedTransferQueue, fallback to LegacyLinkedTransferQueue", t); + } + } + + return new LegacyLinkedTransferQueue(collection); + + } +} diff --git a/src/test/java/org/jboss/netty/channel/socket/AbstractDatagramMulticastTest.java b/src/test/java/org/jboss/netty/channel/socket/AbstractDatagramMulticastTest.java index 823b420b8b..4d19a04204 100644 --- a/src/test/java/org/jboss/netty/channel/socket/AbstractDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/AbstractDatagramMulticastTest.java @@ -20,8 +20,6 @@ import static org.junit.Assert.*; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.NetworkInterface; -import java.net.SocketException; -import java.util.Enumeration; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -31,8 +29,8 @@ import java.util.concurrent.TimeUnit; import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelUpstreamHandler; import org.jboss.netty.util.TestUtil; @@ -65,76 +63,57 @@ public abstract class AbstractDatagramMulticastTest { public void testMulticast() throws Throwable { ConnectionlessBootstrap sb = new ConnectionlessBootstrap(newServerSocketChannelFactory(executor)); ConnectionlessBootstrap cb = new ConnectionlessBootstrap(newClientSocketChannelFactory(executor)); - DatagramChannel sc = null; - DatagramChannel cc = null; - try { - MulticastTestHandler mhandler = new MulticastTestHandler(); + MulticastTestHandler mhandler = new MulticastTestHandler(); - cb.getPipeline().addFirst("handler", mhandler); - sb.getPipeline().addFirst("handler", new SimpleChannelUpstreamHandler()); + cb.getPipeline().addFirst("handler", mhandler); + sb.getPipeline().addFirst("handler", new SimpleChannelUpstreamHandler()); - int port = TestUtil.getFreePort(); + int port = TestUtil.getFreePort(); - NetworkInterface loopbackIf; - try { - loopbackIf = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()); - } catch (SocketException e) { - loopbackIf = null; - } + NetworkInterface iface = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()); - // check if the NetworkInterface is null, this is the case on my ubuntu dev machine but not on osx and windows. - // if so fail back the the first interface - if (loopbackIf == null) { - for (Enumeration e = NetworkInterface.getNetworkInterfaces(); - e.hasMoreElements();) { - NetworkInterface nif = e.nextElement(); - if (nif.isLoopback()) { - loopbackIf = nif; - break; - } - } - } - - sb.setOption("networkInterface", loopbackIf); - sb.setOption("reuseAddress", true); - - sc = (DatagramChannel) sb.bind(new InetSocketAddress(port)); - - - String group = "230.0.0.1"; - InetSocketAddress groupAddress = new InetSocketAddress(group, port); - - cb.setOption("networkInterface", loopbackIf); - cb.setOption("reuseAddress", true); - - cc = (DatagramChannel) cb.bind(new InetSocketAddress(port)); - - assertTrue(cc.joinGroup(groupAddress, loopbackIf).awaitUninterruptibly().isSuccess()); - - assertTrue(sc.write(wrapInt(1), groupAddress).awaitUninterruptibly().isSuccess()); - - assertTrue(mhandler.await()); - - assertTrue(sc.write(wrapInt(1), groupAddress).awaitUninterruptibly().isSuccess()); - - // leave the group - assertTrue(cc.leaveGroup(groupAddress, loopbackIf).awaitUninterruptibly().isSuccess()); - - // sleep a second to make sure we left the group - Thread.sleep(1000); - - // we should not receive a message anymore as we left the group before - assertTrue(sc.write(wrapInt(1), groupAddress).awaitUninterruptibly().isSuccess()); - } finally { - if (sc != null) { - sc.close().awaitUninterruptibly(); - } - if (cc != null) { - cc.close().awaitUninterruptibly(); - } - sb.releaseExternalResources(); - cb.releaseExternalResources(); + // check if the NetworkInterface is null, this is the case on my ubuntu dev machine but not on osx and windows. + // if so fail back the the first interface + if (iface == null) { + // use nextElement() as NetWorkInterface.getByIndex(0) returns null + iface = NetworkInterface.getNetworkInterfaces().nextElement(); } + sb.setOption("networkInterface", iface); + sb.setOption("reuseAddress", true); + + Channel sc = sb.bind(new InetSocketAddress(port)); + + + String group = "230.0.0.1"; + InetSocketAddress groupAddress = new InetSocketAddress(group, port); + + cb.setOption("networkInterface", iface); + cb.setOption("reuseAddress", true); + + DatagramChannel cc = (DatagramChannel) cb.bind(new InetSocketAddress(port)); + + assertTrue(cc.joinGroup(groupAddress, iface).awaitUninterruptibly().isSuccess()); + + assertTrue(sc.write(wrapInt(1), groupAddress).awaitUninterruptibly().isSuccess()); + + + assertTrue(mhandler.await()); + + assertTrue(sc.write(wrapInt(1), groupAddress).awaitUninterruptibly().isSuccess()); + + + // leave the group + assertTrue(cc.leaveGroup(groupAddress, iface).awaitUninterruptibly().isSuccess()); + + // sleep a second to make sure we left the group + Thread.sleep(1000); + + // we should not receive a message anymore as we left the group before + assertTrue(sc.write(wrapInt(1), groupAddress).awaitUninterruptibly().isSuccess()); + + sc.close().awaitUninterruptibly(); + cc.close().awaitUninterruptibly(); + } private static ChannelBuffer wrapInt(int value) { @@ -156,7 +135,7 @@ public abstract class AbstractDatagramMulticastTest { fail = true; } - Assert.assertEquals(1, ((ChannelBuffer)e.getMessage()).readInt()); + Assert.assertEquals(1,((ChannelBuffer)e.getMessage()).readInt()); latch.countDown(); @@ -164,12 +143,6 @@ public abstract class AbstractDatagramMulticastTest { done = true; } - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) - throws Exception { - e.getCause().printStackTrace(); - } - public boolean await() throws Exception { boolean success = latch.await(10, TimeUnit.SECONDS); if (fail) { diff --git a/src/test/java/org/jboss/netty/channel/socket/NioNioDatagramMulticastTest.java b/src/test/java/org/jboss/netty/channel/socket/NioNioDatagramMulticastTest.java index 119a681b86..3e64a0e205 100644 --- a/src/test/java/org/jboss/netty/channel/socket/NioNioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/NioNioDatagramMulticastTest.java @@ -18,9 +18,8 @@ package org.jboss.netty.channel.socket; import java.util.concurrent.Executor; import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; -import org.junit.Ignore; +import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory; -@Ignore public class NioNioDatagramMulticastTest extends AbstractDatagramMulticastTest { @Override @@ -30,7 +29,7 @@ public class NioNioDatagramMulticastTest extends AbstractDatagramMulticastTest { @Override protected DatagramChannelFactory newClientSocketChannelFactory(Executor executor) { - return new NioDatagramChannelFactory(executor, InternetProtocolFamily.IPv4); + return new OioDatagramChannelFactory(executor); } } diff --git a/src/test/java/org/jboss/netty/channel/socket/NioOioDatagramMulticastTest.java b/src/test/java/org/jboss/netty/channel/socket/NioOioDatagramMulticastTest.java index 8c2377b37e..3cc5692632 100644 --- a/src/test/java/org/jboss/netty/channel/socket/NioOioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/NioOioDatagramMulticastTest.java @@ -19,9 +19,7 @@ import java.util.concurrent.Executor; import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory; -import org.junit.Ignore; -@Ignore public class NioOioDatagramMulticastTest extends AbstractDatagramMulticastTest { @Override diff --git a/src/test/java/org/jboss/netty/channel/socket/OioNioDatagramMulticastTest.java b/src/test/java/org/jboss/netty/channel/socket/OioNioDatagramMulticastTest.java index 2dc759f383..f19db682bd 100644 --- a/src/test/java/org/jboss/netty/channel/socket/OioNioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/OioNioDatagramMulticastTest.java @@ -18,10 +18,7 @@ package org.jboss.netty.channel.socket; import java.util.concurrent.Executor; import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory; -import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory; -import org.junit.Ignore; -@Ignore public class OioNioDatagramMulticastTest extends AbstractDatagramMulticastTest { @Override @@ -31,7 +28,7 @@ public class OioNioDatagramMulticastTest extends AbstractDatagramMulticastTest { @Override protected DatagramChannelFactory newClientSocketChannelFactory(Executor executor) { - return new OioDatagramChannelFactory(executor); + return new NioDatagramChannelFactory(executor, InternetProtocolFamily.IPv4); } } diff --git a/src/test/java/org/jboss/netty/channel/socket/OioOioDatagramMulticastTest.java b/src/test/java/org/jboss/netty/channel/socket/OioOioDatagramMulticastTest.java index 8ab63dfda3..3a271b79e0 100644 --- a/src/test/java/org/jboss/netty/channel/socket/OioOioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/OioOioDatagramMulticastTest.java @@ -18,9 +18,7 @@ package org.jboss.netty.channel.socket; import java.util.concurrent.Executor; import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory; -import org.junit.Ignore; -@Ignore public class OioOioDatagramMulticastTest extends AbstractDatagramMulticastTest { @Override