* {@link ChannelBuffer} buffer = ...; @@ -1724,13 +1723,15 @@ 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 df0413ada8..2995542dc6 100644 --- a/src/main/java/org/jboss/netty/buffer/ChannelBuffers.java +++ b/src/main/java/org/jboss/netty/buffer/ChannelBuffers.java @@ -227,7 +227,8 @@ 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); } @@ -308,7 +309,8 @@ 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); } @@ -385,7 +387,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 @@ -399,7 +401,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 @@ -444,7 +446,7 @@ public final class ChannelBuffers { } return EMPTY_BUFFER; } - + /** * Creates a new composite buffer which wraps the slices of the specified @@ -1050,7 +1052,8 @@ 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 { @@ -1118,7 +1121,8 @@ 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; @@ -1133,7 +1137,8 @@ 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 9a014ee481..3c84532832 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 { } /** - * Returntrue
if gathering writes / reads should be used + * Returntrue
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; - this.gathering = buffer.gathering; + 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 0223e303fb..178e098fef 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 preallocatedBufferCapacity; - private ChannelBuffer preallocatedBigEndianBuffer; - private int preallocatedBigEndianBufferPosition; - private ChannelBuffer preallocatedLittleEndianBuffer; - private int preallocatedLittleEndianBufferPosition; + private final int preallocatedBufCapacity; + private ChannelBuffer preallocatedBEBuf; + private int preallocatedBEBufPos; + private ChannelBuffer preallocatedLEBuf; + private int preallocatedLEBufPos; /** * 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( - "preallocatedBufferCapacity must be greater than 0: " + preallocatedBufferCapacity); + "preallocatedBufCapacity must be greater than 0: " + preallocatedBufferCapacity); } - this.preallocatedBufferCapacity = preallocatedBufferCapacity; + this.preallocatedBufCapacity = 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 >= preallocatedBufferCapacity) { + if (capacity >= preallocatedBufCapacity) { return ChannelBuffers.directBuffer(order, capacity); } @@ -160,17 +160,17 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory { private ChannelBuffer allocateBigEndianBuffer(int capacity) { ChannelBuffer slice; synchronized (bigEndianLock) { - 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; + 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; } else { - preallocatedBigEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufferCapacity); - slice = preallocatedBigEndianBuffer.slice(0, capacity); - preallocatedBigEndianBufferPosition = capacity; + preallocatedBEBuf = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufCapacity); + slice = preallocatedBEBuf.slice(0, capacity); + preallocatedBEBufPos = capacity; } } return slice; @@ -179,17 +179,17 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory { private ChannelBuffer allocateLittleEndianBuffer(int capacity) { ChannelBuffer slice; synchronized (littleEndianLock) { - 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; + 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; } else { - preallocatedLittleEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufferCapacity); - slice = preallocatedLittleEndianBuffer.slice(0, capacity); - preallocatedLittleEndianBufferPosition = capacity; + preallocatedLEBuf = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufCapacity); + slice = preallocatedLEBuf.slice(0, capacity); + preallocatedLEBufPos = 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 e0a7d282ab..ccfe617240 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java +++ b/src/main/java/org/jboss/netty/channel/ChannelDownstreamHandler.java @@ -59,7 +59,8 @@ 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 83b297171f..50abd6bbb0 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelEvent.java +++ b/src/main/java/org/jboss/netty/channel/ChannelEvent.java @@ -71,7 +71,8 @@ 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"} @@ -82,7 +83,8 @@ 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"} @@ -91,9 +93,11 @@ 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"} @@ -153,7 +157,8 @@ 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 300348cb6c..31c163385b 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}<Boolean>() { + * public static final {@link ChannelLocal}<Boolean> loggedIn = new {@link ChannelLocal}<>() { * 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 a7aa23a04d..123469f810 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelLocal.java +++ b/src/main/java/org/jboss/netty/channel/ChannelLocal.java @@ -48,7 +48,8 @@ public class ChannelLocal* diff --git a/src/main/java/org/jboss/netty/channel/ChannelState.java b/src/main/java/org/jboss/netty/channel/ChannelState.java index 3d14438038..3aefd47073 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelState.java +++ b/src/main/java/org/jboss/netty/channel/ChannelState.java @@ -29,46 +29,60 @@ import java.net.SocketAddress; *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); @@ -57,7 +58,8 @@ public class ChannelLocalimplements 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 iftrue
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 8a3de0266c..7bc033b75e 100644 --- a/src/main/java/org/jboss/netty/channel/ChannelPipeline.java +++ b/src/main/java/org/jboss/netty/channel/ChannelPipeline.java @@ -168,7 +168,8 @@ 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()); *Direction State Value Meaning *- * *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 integer The channel interestOps has been changed. + *Upstream {@link #INTEREST_OPS} + *an integer The 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 integer Change the interestOps of the channel. + *Downstream {@link #INTEREST_OPS} + *an integer Change 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 d5b69608b3..6bb571e5a9 100644 --- a/src/main/java/org/jboss/netty/channel/SimpleChannelDownstreamHandler.java +++ b/src/main/java/org/jboss/netty/channel/SimpleChannelDownstreamHandler.java @@ -52,7 +52,8 @@ 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 d94855b55b..78321bb61e 100644 --- a/src/main/java/org/jboss/netty/channel/SimpleChannelUpstreamHandler.java +++ b/src/main/java/org/jboss/netty/channel/SimpleChannelUpstreamHandler.java @@ -147,7 +147,8 @@ 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 { @@ -159,7 +160,8 @@ 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 { @@ -171,7 +173,8 @@ 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 d73d2f9172..c0e7ee359e 100644 --- a/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java +++ b/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java @@ -55,7 +55,9 @@ 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 c47832ee3a..cc7471405b 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 if them. + * Release all the previous created channels. + * This takes care of calling {@link LocalChannelRegistry#unregister(LocalAddress)} for each of 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 494ccd0e33..9ae7f37369 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 30fcc229e9..a29c876275 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,9 +49,11 @@ 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)} *@@ -64,64 +66,62 @@ import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory; public interface DatagramChannelConfig extends ChannelConfig { /** - * Gets the {@code SO_SNDBUF} option. + * Gets the {@link StandardSocketOptions#SO_SNDBUF} option. */ int getSendBufferSize(); /** - * Sets the {@code SO_SNDBUF} option. + * Sets the {@link StandardSocketOptions#SO_SNDBUF} option. */ void setSendBufferSize(int sendBufferSize); /** - * Gets the {@code SO_RCVBUF} option. + * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. */ int getReceiveBufferSize(); /** - * Gets the {@code SO_RCVBUF} option. + * Sets the {@link StandardSocketOptions#SO_RCVBUF} option. */ void setReceiveBufferSize(int receiveBufferSize); /** - * Gets the traffic class. + * Gets the {@link StandardSocketOptions#IP_TOS} option. */ int getTrafficClass(); /** - * Sets the traffic class as specified in {@link DatagramSocket#setTrafficClass(int)}. + * Gets the {@link StandardSocketOptions#IP_TOS} option. */ void setTrafficClass(int trafficClass); /** - * Gets the {@code SO_REUSEADDR} option. + * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. */ boolean isReuseAddress(); /** - * Sets the {@code SO_REUSEADDR} option. + * Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. */ void setReuseAddress(boolean reuseAddress); /** - * Gets the {@code SO_BROADCAST} option. + * Gets the {@link StandardSocketOptions#SO_BROADCAST} option. */ boolean isBroadcast(); /** - * Sets the {@code SO_BROADCAST} option. + * Sets the {@link StandardSocketOptions#SO_BROADCAST} option. */ void setBroadcast(boolean broadcast); /** - * Gets the setting for local loopback of multicast datagrams. - * - * @return {@code true} if and only if the loopback mode has been disabled + * Gets the {@link StandardSocketOptions#IP_MULTICAST_LOOP} option. */ boolean isLoopbackModeDisabled(); /** - * Sets the setting for local loopback of multicast datagrams. + * Sets the {@link StandardSocketOptions#IP_MULTICAST_LOOP} option. * * @param loopbackModeDisabled * {@code true} if and only if the loopback mode has been disabled @@ -129,14 +129,12 @@ public interface DatagramChannelConfig extends ChannelConfig { void setLoopbackModeDisabled(boolean loopbackModeDisabled); /** - * Gets the default time-to-live for multicast packets sent out on the - * socket. + * Gets the {@link StandardSocketOptions#IP_MULTICAST_TTL} option. */ int getTimeToLive(); /** - * Sets the default time-to-live for multicast packets sent out on the - * {@link DatagramChannel} in order to control the scope of the multicasts. + * Sets the {@link StandardSocketOptions#IP_MULTICAST_TTL} option. */ void setTimeToLive(int ttl); @@ -151,14 +149,12 @@ public interface DatagramChannelConfig extends ChannelConfig { void setInterface(InetAddress interfaceAddress); /** - * Gets the network interface for outgoing multicast datagrams sent on - * the {@link DatagramChannel}. + * Gets the {@link StandardSocketOptions#IP_MULTICAST_IF} option. */ NetworkInterface getNetworkInterface(); /** - * Sets the network interface for outgoing multicast datagrams sent on - * the {@link DatagramChannel}. + * Sets the {@link StandardSocketOptions#IP_MULTICAST_IF} option. */ 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 54a32d5fb4..cdae6dea9a 100644 --- a/src/main/java/org/jboss/netty/channel/socket/ServerSocketChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/ServerSocketChannelConfig.java @@ -16,6 +16,7 @@ package org.jboss.netty.channel.socket; import java.net.ServerSocket; +import java.net.StandardSocketOptions; import org.jboss.netty.channel.ChannelConfig; @@ -55,22 +56,22 @@ public interface ServerSocketChannelConfig extends ChannelConfig { void setBacklog(int backlog); /** - * Gets the {@code SO_REUSEADDR} option. + * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. */ boolean isReuseAddress(); /** - * Sets the {@code SO_REUSEADDR} option. + * Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. */ void setReuseAddress(boolean reuseAddress); /** - * Gets the {@code SO_RCVBUF} option. + * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. */ int getReceiveBufferSize(); /** - * Sets the {@code SO_RCVBUF} option. + * Sets the {@link StandardSocketOptions#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 05498b7f40..8064c12de0 100644 --- a/src/main/java/org/jboss/netty/channel/socket/SocketChannelConfig.java +++ b/src/main/java/org/jboss/netty/channel/socket/SocketChannelConfig.java @@ -16,6 +16,7 @@ package org.jboss.netty.channel.socket; import java.net.Socket; +import java.net.StandardSocketOptions; import org.jboss.netty.channel.ChannelConfig; @@ -50,72 +51,72 @@ import org.jboss.netty.channel.ChannelConfig; public interface SocketChannelConfig extends ChannelConfig { /** - * Gets the {@code SO_TCPNODELAY} option. + * Gets the {@link StandardSocketOptions#TCP_NODELAY} option. */ boolean isTcpNoDelay(); /** - * Sets the {@code SO_TCPNODELAY} option. + * Sets the {@link StandardSocketOptions#TCP_NODELAY} option. */ void setTcpNoDelay(boolean tcpNoDelay); /** - * Gets the {@code SO_LINGER} option. + * Gets the {@link StandardSocketOptions#SO_LINGER} option. */ int getSoLinger(); /** - * Sets the {@code SO_LINGER} option. + * Sets the {@link StandardSocketOptions#SO_LINGER} option. */ void setSoLinger(int soLinger); /** - * Gets the {@code SO_SNDBUF} option. + * Gets the {@link StandardSocketOptions#SO_SNDBUF} option. */ int getSendBufferSize(); /** - * Sets the {@code SO_SNDBUF} option. + * Sets the {@link StandardSocketOptions#SO_SNDBUF} option. */ void setSendBufferSize(int sendBufferSize); /** - * Gets the {@code SO_RCVBUF} option. + * Gets the {@link StandardSocketOptions#SO_RCVBUF} option. */ int getReceiveBufferSize(); /** - * Gets the {@code SO_RCVBUF} option. + * Sets the {@link StandardSocketOptions#SO_RCVBUF} option. */ void setReceiveBufferSize(int receiveBufferSize); /** - * Gets the {@code SO_KEEPALIVE} option. + * Gets the {@link StandardSocketOptions#SO_KEEPALIVE} option. */ boolean isKeepAlive(); /** - * Sets the {@code SO_KEEPALIVE} option. + * Sets the {@link StandardSocketOptions#SO_KEEPALIVE} option. */ void setKeepAlive(boolean keepAlive); /** - * Gets the traffic class. + * Gets the {@link StandardSocketOptions#IP_TOS} option. */ int getTrafficClass(); /** - * Sets the traffic class as specified in {@link Socket#setTrafficClass(int)}. + * Sets the {@link StandardSocketOptions#IP_TOS} option. */ void setTrafficClass(int trafficClass); /** - * Gets the {@code SO_REUSEADDR} option. + * Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. */ boolean isReuseAddress(); /** - * Sets the {@code SO_REUSEADDR} option. + * Sets the {@link StandardSocketOptions#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 c69c24912a..07780d344c 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 31421411c1..e88eff5059 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,368 +1,370 @@ -/* - * 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 extends MessageEvent> 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 super MessageEvent> c) { - return queue.drainTo(c); - } - - public int drainTo(Collection super MessageEvent> 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 extends MessageEvent> 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 super MessageEvent> c) { + return queue.drainTo(c); + } + + public int drainTo(Collection super MessageEvent> 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 b54d1f15f5..13f52a53bf 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 c5e6df1004..336677e270 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,824 +1,825 @@ -/* - * 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(SetselectedKeys) 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(SetselectedKeys) 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 b3400c9832..8723ebd1df 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,83 +1,85 @@ -/* - * 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 3f963878fd..b9156a3c10 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 0bb3ff13c8..406906efb6 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,7 +88,8 @@ 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 0eeec0b834..bdc637b281 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,7 +130,8 @@ public final class NioDatagramChannel extends AbstractNioChannel workerPool) { this(workerPool, null); @@ -186,7 +187,8 @@ 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 589899c372..5a108af50c 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,8 +38,9 @@ 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 7b53e80cf4..a2e8fa8c9c 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 b18825d9ca..cca91c0647 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,7 +90,8 @@ 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)} */ @@ -136,7 +137,8 @@ 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 8d08e1328e..343ddc0dcc 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,9 +42,11 @@ import org.jboss.netty.channel.socket.SocketChannelConfig; * * {@code "writeSpinCount"} {@link #setWriteSpinCount(int)} *- * {@code "receiveBufferSizePredictor"} {@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} + *{@code "receiveBufferSizePredictor"} + *{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)} *- * * */ 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 950cad76bd..2b08cf1157 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{@code "receiveBufferSizePredictorFactory"} {@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} + *{@code "receiveBufferSizePredictorFactory"} + *{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)} *{ - - 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 8664731809..e7ced7207b 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,47 +1,48 @@ -/* - * 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 ea7efa5d3c..7924bc7a7f 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,7 +27,6 @@ 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 { @@ -368,7 +367,8 @@ 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 29053ac5d1..4b049ffdba 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 d64ee29a22..56da38bf35 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 e74b2c5dc3..00f4107e2f 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 b2485fd6df..d5d85fe6f2 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,241 +1,243 @@ -/* - * 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 405f60e3fc..2e74fe4e16 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,7 +91,8 @@ 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 1d3cc8c685..78b5512d9c 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 69ccf3c430..c908936779 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,7 +138,8 @@ 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) { @@ -297,7 +298,8 @@ 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 af5ed1bb9c..d06a8cc456 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,7 +132,8 @@ 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 e4d4d31913..4e844afdfb 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,7 +430,8 @@ public class HttpUploadServerHandler extends SimpleChannelUpstreamHandler { responseContent .append(" Fill with value:
"); responseContent - .append("Fill with file (only file name will be transmitted):
"); + .append(""); responseContent .append(" Fill with file (only file name will be transmitted):
" + + ""); 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 a841e80b17..866a80427d 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,67 +27,50 @@ 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 + "" + NEWLINE, - CharsetUtil.US_ASCII); + return ChannelBuffers.copiedBuffer( + "Web Socket Test " + NEWLINE + + "" + 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 1bbb03751c..de7759eff0 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,6 +29,7 @@ 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; @@ -75,7 +76,7 @@ public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler { if (req.getUri().equals("/")) { HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); - ChannelBuffer content = WebSocketSslServerIndexPage.getContent(getWebSocketLocation(req)); + ChannelBuffer content = WebSocketServerIndexPage.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 deleted file mode 100644 index 96230a5351..0000000000 --- a/src/main/java/org/jboss/netty/example/http/websocketx/sslserver/WebSocketSslServerIndexPage.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 + "" + 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 8cd31d3bfb..65c56b5bd7 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 47a55f59b9..ad65eacd1a 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 e427a74f99..39567a6880 100644 --- a/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFactory.java +++ b/src/main/java/org/jboss/netty/example/securechat/SecureChatSslContextFactory.java @@ -16,6 +16,7 @@ package org.jboss.netty.example.securechat; import java.security.KeyStore; +import java.security.SecureRandom; import java.security.Security; import javax.net.ssl.KeyManager; @@ -42,10 +43,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[], javax.net.ssl.TrustManager[], java.security.SecureRandom)}. + * the first argument of {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}. *When initializing an {@link SSLContext} on the server side, * specify the proper {@link TrustManager} as the second argument of - * {@link SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)} + * {@link SSLContext#init(KeyManager[], TrustManager[], 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 2077d3562a..b9d9d574e8 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,7 +28,9 @@ 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 */ @@ -125,7 +127,8 @@ 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 2293606bea..edaa007f8f 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,7 +23,8 @@ 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 a709ec6179..81e8f307e2 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,7 +25,8 @@ 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 8c244dac38..b6a1928de9 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 ChannelBuffer}>( + * {@link EncoderEmbedder}<{@link ChannelBuffer}> embedder = new {@link EncoderEmbedder}<>( * 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 6bc41d2400..bdf42f4ef8 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,8 +51,11 @@ public class FixedLengthFrameDecoder extends FrameDecoder { /** * Creates a new instance. * - * @param frameLength the length of the frame - * @param allocateFullBuffer* * 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 38e68374fb..5dd813ad73 100644 --- a/src/main/java/org/jboss/netty/handler/ipfilter/IpFilterRuleHandler.java +++ b/src/main/java/org/jboss/netty/handler/ipfilter/IpFilterRuleHandler.java @@ -30,7 +30,8 @@ import org.jboss.netty.channel.ChannelHandlerContext; * Implementation of Filter of IP based on ALLOW and DENY rules.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 6499a21003..3e313ba9c9 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,7 +214,8 @@ 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); } } @@ -350,7 +351,8 @@ 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) { @@ -369,8 +371,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 { @@ -420,7 +422,8 @@ 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 39acbc2cc1..2f3d1ad423 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 ba05c91d38..51352742d8 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,7 +219,8 @@ 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 578bbeb2d0..fdbcb794cb 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,7 +150,8 @@ 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 4a11def611..bbfeed3415 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,7 +167,8 @@ 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"); @@ -63,17 +67,20 @@ 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 f7129a8826..450eeba11e 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,7 +102,9 @@ 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 9d05f80fef..5dcc35da19 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,7 +56,8 @@ 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 @@ -151,7 +152,8 @@ 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 @@ -181,7 +183,8 @@ 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 @@ -191,12 +194,14 @@ 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 @@ -231,7 +236,8 @@ 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 @@ -256,12 +262,14 @@ 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 1e81bbbe77..21b1d729d6 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 4284b4956d..30826d90f9 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,7 +461,8 @@ 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); @@ -587,7 +588,8 @@ 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 90c818572e..b4a9f1574c 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,7 +35,8 @@ 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. @@ -72,7 +73,8 @@ 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 3404c76156..67c2de53ad 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,19 +18,20 @@ * * 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 769d5ad370..f753a755f9 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,19 +18,20 @@ * * 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; @@ -41,20 +42,23 @@ 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 29bae6efb0..105b4a722e 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,20 +59,24 @@ 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. - * @throws WebSocketHandshakeException + * Maximum allowable frame payload length. Setting this value to your application's + * requirement may reduce denial of service attacks using long data frames. */ - 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 02de80477a..d9746ced36 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 f7021f2817..2c512c1004 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,16 +82,19 @@ 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 6f1372d4bf..8806b0294e 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,9 +21,10 @@ * This package supports different web socket specification versions (hence the X suffix). * The specification current supported are: * - *
* *- draft-ietf-hybi-thewebsocketprotocol-00
- *- draft-ietf-hybi-thewebsocketprotocol-10
- *- RFC 6455 (originally draft-ietf-hybi-thewebsocketprotocol-17)
+ *- draft-ietf-hybi-thewebsocketprotocol-00
+ *- draft-ietf-hybi-thewebsocketprotocol-10
+ *- RFC 6455 (originally + * draft-ietf-hybi-thewebsocketprotocol-17)
*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 e63fcb2d59..4901666607 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,12 +42,15 @@ 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; @@ -55,7 +58,8 @@ 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 7592190f87..bbfa687604 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,7 +50,8 @@ 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(); @@ -58,5 +59,4 @@ 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 6d8976e7bf..f4a55a39f8 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,7 +27,8 @@ 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 { @@ -77,8 +78,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 ffdf9393b1..8b7550d296 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,7 +75,8 @@ 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 f88e5a4027..8a7ee1f726 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,8 +389,9 @@ 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 { @@ -520,7 +521,9 @@ 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 39fd549d08..1470d4807b 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,10 +27,11 @@ 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 d198eeef82..665ac118f1 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,7 +107,8 @@ 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 8fbba7a63d..8500cd32b1 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,7 +38,9 @@ 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 >>())); } /** @@ -49,7 +51,9 @@ 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 >>())); } /** @@ -60,7 +64,9 @@ 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 >>())); } /** @@ -71,7 +77,9 @@ 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 6823911935..8afa62e1e6 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,7 +74,8 @@ public class CompatibleObjectDecoder extends ReplayingDecoder true 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 ba8433cdb1..caac49aa31 100644 --- a/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnable.java +++ b/src/main/java/org/jboss/netty/handler/execution/ChannelUpstreamEventRunnable.java @@ -32,15 +32,16 @@ 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) { - super(ctx, e); + public ChannelUpstreamEventRunnable(ChannelHandlerContext ctx, ChannelEvent e, Executor executor) { + super(ctx, e, executor); } /** * Sends the event upstream. */ - public void run() { + @Override + protected void doRun() { 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 4d1f9bd0c3..49655a44c6 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 d65a05e4ef..dde16c540d 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.execute(new ChannelUpstreamEventRunnable(context, e, executor)); } 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.execute(new ChannelDownstreamEventRunnable(ctx, e, executor)); } 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 13adf11d1e..1431438054 100644 --- a/src/main/java/org/jboss/netty/handler/execution/MemoryAwareThreadPoolExecutor.java +++ b/src/main/java/org/jboss/netty/handler/execution/MemoryAwareThreadPoolExecutor.java @@ -182,7 +182,9 @@ 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()); } /** @@ -201,7 +203,9 @@ 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); } /** @@ -277,11 +281,13 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { } /** - * See {@link ThreadPoolExecutor#shutdownNow()} for how it handles the shutdown. Iftrue
is given to this method it also notifies all {@link ChannelFuture}'s + * See {@link ThreadPoolExecutor#shutdownNow()} for how it handles the shutdown. + * Iftrue
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
* @@ -395,11 +401,13 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor { } /** - * If set tofalse
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 withfalse
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. *false
no queued {@link ChannelEventRunnable}'s {@link ChannelFuture} will get notified once {@link #shutdownNow()} is called. - * If set totrue
every queued {@link ChannelEventRunnable} will get marked as failed via {@link ChannelFuture#setFailure(Throwable)}. + * If set tofalse
no queued {@link ChannelEventRunnable}'s {@link ChannelFuture} + * will get notified once {@link #shutdownNow()} is called. If set totrue
every + * queued {@link ChannelEventRunnable} will get marked as failed via {@link ChannelFuture#setFailure(Throwable)}. * *- * Please only set this to
*/ public void setNotifyChannelFuturesOnShutdown(boolean notifyOnShutdown) { @@ -407,8 +415,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; @@ -524,8 +532,9 @@ 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 a6b75f8e91..b91e6f566f 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}. *false
if you want to handle the notification by yourself and know what you are doing. Default istrue
. + * Please only set this tofalse
if you want to handle the notification by yourself + * and know what you are doing. Default istrue
. *
*
- * * For more informations about how the order is preserved see {@link OrderedMemoryAwareThreadPoolExecutor} - * */ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwareThreadPoolExecutor { @@ -83,7 +83,8 @@ 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) { @@ -99,7 +100,8 @@ 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) { @@ -115,7 +117,8 @@ 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 37f2932112..345bd9121b 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; *
*
* 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 e52fad7309..4ac2390535 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,17 +18,20 @@ * 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:
*- *
* @@ -42,27 +45,32 @@ * this method is already implemented.- {@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.
* *
*
* - *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.
@@ -70,7 +78,8 @@ * 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 d206394bdb..9fd5f57dc2 100644 --- a/src/main/java/org/jboss/netty/handler/queue/BlockingReadHandler.java +++ b/src/main/java/org/jboss/netty/handler/queue/BlockingReadHandler.java @@ -219,7 +219,8 @@ public class BlockingReadHandlerextends 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 bae13234f2..d9b042efc5 100644 --- a/src/main/java/org/jboss/netty/handler/queue/BufferedWriteHandler.java +++ b/src/main/java/org/jboss/netty/handler/queue/BufferedWriteHandler.java @@ -142,7 +142,8 @@ 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(); * } @@ -355,7 +356,8 @@ 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 { @@ -396,7 +398,8 @@ 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 a2748e4d8a..a5c59f84db 100644 --- a/src/main/java/org/jboss/netty/handler/ssl/SslHandler.java +++ b/src/main/java/org/jboss/netty/handler/ssl/SslHandler.java @@ -70,9 +70,10 @@ 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 totrue
+ * you don't need to worry about this as the {@link SslHandler} will take care of it. ** *
Renegotiation
@@ -91,7 +92,8 @@ import org.jboss.netty.util.internal.QueueFactory; **
* *- CVE-2009-3555
*- RFC5746
- *- Phased Approach to Fixing the TLS Renegotiation Issue
+ *- Phased + * Approach to Fixing the TLS Renegotiation Issue
*Closing the session
@@ -869,7 +871,8 @@ 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 @@ -939,7 +942,8 @@ 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(); @@ -1275,7 +1279,8 @@ 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 3811234585..6d78475ad4 100644 --- a/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java +++ b/src/main/java/org/jboss/netty/handler/stream/ChunkedWriteHandler.java @@ -73,7 +73,8 @@ 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); @@ -251,8 +252,9 @@ public class ChunkedWriteHandler implements ChannelUpstreamHandler, ChannelDowns 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 a191f813e8..33762355d3 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,14 +25,16 @@ * *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 see {@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 + * {@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} @@ -62,14 +64,16 @@ * [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}.
* *
@@ -81,8 +85,9 @@ * 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 8529fcc5e1..0d6e812d6f 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 offalse
. Default istrue
. - */ -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; - } - - /** - * Returntrue
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 offalse
. Default istrue
. + */ +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; + } + + /** + * Returntrue
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 8e039620c3..6dfe83a39e 100644 --- a/src/main/java/org/jboss/netty/util/internal/QueueFactory.java +++ b/src/main/java/org/jboss/netty/util/internal/QueueFactory.java @@ -1,100 +1,102 @@ -/* - * 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 extends T> 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 extends T> 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 4d19a04204..823b420b8b 100644 --- a/src/test/java/org/jboss/netty/channel/socket/AbstractDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/AbstractDatagramMulticastTest.java @@ -20,6 +20,8 @@ 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; @@ -29,8 +31,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; @@ -63,57 +65,76 @@ public abstract class AbstractDatagramMulticastTest { public void testMulticast() throws Throwable { ConnectionlessBootstrap sb = new ConnectionlessBootstrap(newServerSocketChannelFactory(executor)); ConnectionlessBootstrap cb = new ConnectionlessBootstrap(newClientSocketChannelFactory(executor)); - MulticastTestHandler mhandler = new MulticastTestHandler(); + DatagramChannel sc = null; + DatagramChannel cc = null; + try { + 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 iface = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()); + NetworkInterface loopbackIf; + try { + loopbackIf = NetworkInterface.getByInetAddress(InetAddress.getLocalHost()); + } catch (SocketException e) { + loopbackIf = null; + } - // 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(); + // 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(); } - 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) { @@ -135,7 +156,7 @@ public abstract class AbstractDatagramMulticastTest { fail = true; } - Assert.assertEquals(1,((ChannelBuffer)e.getMessage()).readInt()); + Assert.assertEquals(1, ((ChannelBuffer)e.getMessage()).readInt()); latch.countDown(); @@ -143,6 +164,12 @@ 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 3e64a0e205..119a681b86 100644 --- a/src/test/java/org/jboss/netty/channel/socket/NioNioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/NioNioDatagramMulticastTest.java @@ -18,8 +18,9 @@ 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 NioNioDatagramMulticastTest extends AbstractDatagramMulticastTest { @Override @@ -29,7 +30,7 @@ public class NioNioDatagramMulticastTest 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/NioOioDatagramMulticastTest.java b/src/test/java/org/jboss/netty/channel/socket/NioOioDatagramMulticastTest.java index 3cc5692632..8c2377b37e 100644 --- a/src/test/java/org/jboss/netty/channel/socket/NioOioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/NioOioDatagramMulticastTest.java @@ -19,7 +19,9 @@ 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 f19db682bd..2dc759f383 100644 --- a/src/test/java/org/jboss/netty/channel/socket/OioNioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/OioNioDatagramMulticastTest.java @@ -18,7 +18,10 @@ 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 @@ -28,7 +31,7 @@ public class OioNioDatagramMulticastTest 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/OioOioDatagramMulticastTest.java b/src/test/java/org/jboss/netty/channel/socket/OioOioDatagramMulticastTest.java index 3a271b79e0..8ab63dfda3 100644 --- a/src/test/java/org/jboss/netty/channel/socket/OioOioDatagramMulticastTest.java +++ b/src/test/java/org/jboss/netty/channel/socket/OioOioDatagramMulticastTest.java @@ -18,7 +18,9 @@ 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