Revert "Merge branch '3' of ssh://github.com/netty/netty into 3"

This reverts commit 7d8a6f9c8e, reversing
changes made to 78da141c9d.
This commit is contained in:
norman 2012-06-11 10:07:46 +02:00
parent 7d8a6f9c8e
commit 91accdc5e4
111 changed files with 3082 additions and 3203 deletions

10
pom.xml
View File

@ -26,7 +26,7 @@
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty</artifactId> <artifactId>netty</artifactId>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<version>3.5.1.Final-SNAPSHOT</version> <version>3.5.0.Final-SNAPSHOT</version>
<name>The Netty Project</name> <name>The Netty Project</name>
<url>http://netty.io/</url> <url>http://netty.io/</url>
@ -577,10 +577,10 @@
<doctitle>${project.name} API Reference (${project.version})</doctitle> <doctitle>${project.name} API Reference (${project.version})</doctitle>
<windowtitle>${project.name} API Reference (${project.version})</windowtitle> <windowtitle>${project.name} API Reference (${project.version})</windowtitle>
<additionalparam> <additionalparam>
-link http://docs.oracle.com/javase/7/docs/api/ -link http://java.sun.com/javase/6/docs/api/
-link http://code.google.com/apis/protocolbuffers/docs/reference/java/ -link http://code.google.com/apis/protocolbuffers/docs/reference/java/
-link http://docs.oracle.com/javaee/6/api/ -link http://java.sun.com/products/servlet/2.5/docs/servlet-2_5-mr2/
-link http://www.osgi.org/javadoc/r4v43/core/ -link http://www.osgi.org/javadoc/r4v41/
-link http://www.slf4j.org/apidocs/ -link http://www.slf4j.org/apidocs/
-link http://commons.apache.org/logging/commons-logging-1.1.1/apidocs/ -link http://commons.apache.org/logging/commons-logging-1.1.1/apidocs/
-link http://logging.apache.org/log4j/1.2/apidocs/ -link http://logging.apache.org/log4j/1.2/apidocs/
@ -665,7 +665,7 @@
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>netty-build</artifactId> <artifactId>netty-build</artifactId>
<version>9</version> <version>7</version>
</dependency> </dependency>
</dependencies> </dependencies>
</plugin> </plugin>

View File

@ -34,7 +34,6 @@
<include>**/src/**</include> <include>**/src/**</include>
</includes> </includes>
<excludes> <excludes>
<exclude>**/bin/**</exclude>
<exclude>**/target/**</exclude> <exclude>**/target/**</exclude>
<exclude>**/.*/**</exclude> <exclude>**/.*/**</exclude>
</excludes> </excludes>

View File

@ -231,13 +231,12 @@ public class ClientBootstrap extends Bootstrap {
} }
/** /**
* Attempts to bind a channel with the specified {@code localAddress}. later the channel can * Attempts to bind a channel with the specified {@code localAddress}. later the channel can be connected
* be connected to a remoteAddress by calling {@link Channel#connect(SocketAddress)}.This method * to a remoteAddress by calling {@link Channel#connect(SocketAddress)}.This method is useful where bind and connect
* is useful where bind and connect need to be done in separate steps. * need to be done in separate steps.
* *
* This can also be useful if you want to set an attachment to the {@link Channel} via * This can also be useful if you want to set an attachment to the {@link Channel} via
* {@link Channel#setAttachment(Object)} so you can use it after the {@link #bind(SocketAddress)} * {@link Channel#setAttachment(Object)} so you can use it after the {@link #bind(SocketAddress)} was done.
* was done.
* <br> * <br>
* For example: * For example:
* *

View File

@ -39,10 +39,11 @@ import java.nio.charset.UnsupportedCharsetException;
* <h3>Random Access Indexing</h3> * <h3>Random Access Indexing</h3>
* *
* Just like an ordinary primitive byte array, {@link ChannelBuffer} uses * Just like an ordinary primitive byte array, {@link ChannelBuffer} uses
* <a href="http://en.wikipedia.org/wiki/Zero-based_numbering">zero-based indexing</a>. * <a href="http://en.wikipedia.org/wiki/Index_(information_technology)#Array_element_identifier">zero-based indexing</a>.
* It means the index of the first byte is always {@code 0} and the index of the last byte is * It means the index of the first byte is always {@code 0} and the index of
* always {@link #capacity() capacity - 1}. For example, to iterate all bytes of a buffer, you * the last byte is always {@link #capacity() capacity - 1}. For example, to
* can do the following, regardless of its internal implementation: * iterate all bytes of a buffer, you can do the following, regardless of
* its internal implementation:
* *
* <pre> * <pre>
* {@link ChannelBuffer} buffer = ...; * {@link ChannelBuffer} buffer = ...;
@ -1723,15 +1724,13 @@ public interface ChannelBuffer extends Comparable<ChannelBuffer> {
String charsetName, ChannelBufferIndexFinder terminatorFinder); String charsetName, ChannelBufferIndexFinder terminatorFinder);
/** /**
* @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
* {@link #toString(int, int, Charset)} instead.
*/ */
@Deprecated @Deprecated
String toString(int index, int length, String charsetName); String toString(int index, int length, String charsetName);
/** /**
* @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and * @deprecated Use {@link #bytesBefore(int, int, ChannelBufferIndexFinder)} and {@link #toString(int, int, Charset)} instead.
* {@link #toString(int, int, Charset)} instead.
*/ */
@Deprecated @Deprecated
String toString( String toString(

View File

@ -227,8 +227,7 @@ public final class ChannelBuffers {
* More accurate estimation yields less unexpected reallocation overhead. * More accurate estimation yields less unexpected reallocation overhead.
* The new buffer's {@code readerIndex} and {@code writerIndex} are {@code 0}. * The new buffer's {@code readerIndex} and {@code writerIndex} are {@code 0}.
*/ */
public static ChannelBuffer dynamicBuffer( public static ChannelBuffer dynamicBuffer(ByteOrder endianness, int estimatedLength, ChannelBufferFactory factory) {
ByteOrder endianness, int estimatedLength, ChannelBufferFactory factory) {
return new DynamicChannelBuffer(endianness, estimatedLength, factory); return new DynamicChannelBuffer(endianness, estimatedLength, factory);
} }
@ -309,8 +308,7 @@ public final class ChannelBuffers {
return EMPTY_BUFFER; return EMPTY_BUFFER;
} }
if (buffer.hasArray()) { if (buffer.hasArray()) {
return wrappedBuffer( return wrappedBuffer(buffer.order(), buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
buffer.order(), buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining());
} else { } else {
return new ByteBufferBackedChannelBuffer(buffer); return new ByteBufferBackedChannelBuffer(buffer);
} }
@ -387,7 +385,7 @@ public final class ChannelBuffers {
* Creates a new composite buffer which wraps the readable bytes of the * Creates a new composite buffer which wraps the readable bytes of the
* specified buffers without copying them. A modification on the content * specified buffers without copying them. A modification on the content
* of the specified buffers will be visible to the returned buffer. * of the specified buffers will be visible to the returned buffer.
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the specified buffers' endianness are different from each * if the specified buffers' endianness are different from each
* other * other
@ -401,7 +399,7 @@ public final class ChannelBuffers {
* of the specified buffers will be visible to the returned buffer. * of the specified buffers will be visible to the returned buffer.
* If gathering is <code>true</code> then gathering writes will be used when ever * If gathering is <code>true</code> then gathering writes will be used when ever
* possible. * possible.
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the specified buffers' endianness are different from each * if the specified buffers' endianness are different from each
* other * other
@ -446,7 +444,7 @@ public final class ChannelBuffers {
} }
return EMPTY_BUFFER; return EMPTY_BUFFER;
} }
/** /**
* Creates a new composite buffer which wraps the slices of the specified * Creates a new composite buffer which wraps the slices of the specified
@ -1052,8 +1050,7 @@ public final class ChannelBuffers {
* The default implementation of {@link ChannelBuffer#indexOf(int, int, ChannelBufferIndexFinder)}. * The default implementation of {@link ChannelBuffer#indexOf(int, int, ChannelBufferIndexFinder)}.
* This method is useful when implementing a new buffer type. * This method is useful when implementing a new buffer type.
*/ */
public static int indexOf( public static int indexOf(ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
if (fromIndex <= toIndex) { if (fromIndex <= toIndex) {
return firstIndexOf(buffer, fromIndex, toIndex, indexFinder); return firstIndexOf(buffer, fromIndex, toIndex, indexFinder);
} else { } else {
@ -1121,8 +1118,7 @@ public final class ChannelBuffers {
return -1; return -1;
} }
private static int firstIndexOf( private static int firstIndexOf(ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
fromIndex = Math.max(fromIndex, 0); fromIndex = Math.max(fromIndex, 0);
if (fromIndex >= toIndex || buffer.capacity() == 0) { if (fromIndex >= toIndex || buffer.capacity() == 0) {
return -1; return -1;
@ -1137,8 +1133,7 @@ public final class ChannelBuffers {
return -1; return -1;
} }
private static int lastIndexOf( private static int lastIndexOf(ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
ChannelBuffer buffer, int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
fromIndex = Math.min(fromIndex, buffer.capacity()); fromIndex = Math.min(fromIndex, buffer.capacity());
if (fromIndex < 0 || buffer.capacity() == 0) { if (fromIndex < 0 || buffer.capacity() == 0) {
return -1; return -1;

View File

@ -48,13 +48,13 @@ public class CompositeChannelBuffer extends AbstractChannelBuffer {
} }
/** /**
* Return <code>true</code> if gathering writes / reads should be used * Return <code>true</code> if gathering writes / reads should be used
* for this {@link CompositeChannelBuffer} * for this {@link CompositeChannelBuffer}
*/ */
public boolean useGathering() { public boolean useGathering() {
return gathering && DetectionUtil.javaVersion() >= 7; return gathering && DetectionUtil.javaVersion() >= 7;
} }
/** /**
* Same with {@link #slice(int, int)} except that this method returns a list. * 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) { private CompositeChannelBuffer(CompositeChannelBuffer buffer) {
order = buffer.order; order = buffer.order;
gathering = buffer.gathering; this.gathering = buffer.gathering;
components = buffer.components.clone(); components = buffer.components.clone();
indices = buffer.indices.clone(); indices = buffer.indices.clone();
setIndex(buffer.readerIndex(), buffer.writerIndex()); setIndex(buffer.readerIndex(), buffer.writerIndex());

View File

@ -56,11 +56,11 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
private final Object bigEndianLock = new Object(); private final Object bigEndianLock = new Object();
private final Object littleEndianLock = new Object(); private final Object littleEndianLock = new Object();
private final int preallocatedBufCapacity; private final int preallocatedBufferCapacity;
private ChannelBuffer preallocatedBEBuf; private ChannelBuffer preallocatedBigEndianBuffer;
private int preallocatedBEBufPos; private int preallocatedBigEndianBufferPosition;
private ChannelBuffer preallocatedLEBuf; private ChannelBuffer preallocatedLittleEndianBuffer;
private int preallocatedLEBufPos; private int preallocatedLittleEndianBufferPosition;
/** /**
* Creates a new factory whose default {@link ByteOrder} is * Creates a new factory whose default {@link ByteOrder} is
@ -96,10 +96,10 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
super(defaultOrder); super(defaultOrder);
if (preallocatedBufferCapacity <= 0) { if (preallocatedBufferCapacity <= 0) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"preallocatedBufCapacity must be greater than 0: " + preallocatedBufferCapacity); "preallocatedBufferCapacity must be greater than 0: " + preallocatedBufferCapacity);
} }
this.preallocatedBufCapacity = preallocatedBufferCapacity; this.preallocatedBufferCapacity = preallocatedBufferCapacity;
} }
public ChannelBuffer getBuffer(ByteOrder order, int capacity) { public ChannelBuffer getBuffer(ByteOrder order, int capacity) {
@ -112,7 +112,7 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
if (capacity == 0) { if (capacity == 0) {
return ChannelBuffers.EMPTY_BUFFER; return ChannelBuffers.EMPTY_BUFFER;
} }
if (capacity >= preallocatedBufCapacity) { if (capacity >= preallocatedBufferCapacity) {
return ChannelBuffers.directBuffer(order, capacity); return ChannelBuffers.directBuffer(order, capacity);
} }
@ -160,17 +160,17 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
private ChannelBuffer allocateBigEndianBuffer(int capacity) { private ChannelBuffer allocateBigEndianBuffer(int capacity) {
ChannelBuffer slice; ChannelBuffer slice;
synchronized (bigEndianLock) { synchronized (bigEndianLock) {
if (preallocatedBEBuf == null) { if (preallocatedBigEndianBuffer == null) {
preallocatedBEBuf = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufCapacity); preallocatedBigEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufferCapacity);
slice = preallocatedBEBuf.slice(0, capacity); slice = preallocatedBigEndianBuffer.slice(0, capacity);
preallocatedBEBufPos = capacity; preallocatedBigEndianBufferPosition = capacity;
} else if (preallocatedBEBuf.capacity() - preallocatedBEBufPos >= capacity) { } else if (preallocatedBigEndianBuffer.capacity() - preallocatedBigEndianBufferPosition >= capacity) {
slice = preallocatedBEBuf.slice(preallocatedBEBufPos, capacity); slice = preallocatedBigEndianBuffer.slice(preallocatedBigEndianBufferPosition, capacity);
preallocatedBEBufPos += capacity; preallocatedBigEndianBufferPosition += capacity;
} else { } else {
preallocatedBEBuf = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufCapacity); preallocatedBigEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.BIG_ENDIAN, preallocatedBufferCapacity);
slice = preallocatedBEBuf.slice(0, capacity); slice = preallocatedBigEndianBuffer.slice(0, capacity);
preallocatedBEBufPos = capacity; preallocatedBigEndianBufferPosition = capacity;
} }
} }
return slice; return slice;
@ -179,17 +179,17 @@ public class DirectChannelBufferFactory extends AbstractChannelBufferFactory {
private ChannelBuffer allocateLittleEndianBuffer(int capacity) { private ChannelBuffer allocateLittleEndianBuffer(int capacity) {
ChannelBuffer slice; ChannelBuffer slice;
synchronized (littleEndianLock) { synchronized (littleEndianLock) {
if (preallocatedLEBuf == null) { if (preallocatedLittleEndianBuffer == null) {
preallocatedLEBuf = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufCapacity); preallocatedLittleEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufferCapacity);
slice = preallocatedLEBuf.slice(0, capacity); slice = preallocatedLittleEndianBuffer.slice(0, capacity);
preallocatedLEBufPos = capacity; preallocatedLittleEndianBufferPosition = capacity;
} else if (preallocatedLEBuf.capacity() - preallocatedLEBufPos >= capacity) { } else if (preallocatedLittleEndianBuffer.capacity() - preallocatedLittleEndianBufferPosition >= capacity) {
slice = preallocatedLEBuf.slice(preallocatedLEBufPos, capacity); slice = preallocatedLittleEndianBuffer.slice(preallocatedLittleEndianBufferPosition, capacity);
preallocatedLEBufPos += capacity; preallocatedLittleEndianBufferPosition += capacity;
} else { } else {
preallocatedLEBuf = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufCapacity); preallocatedLittleEndianBuffer = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, preallocatedBufferCapacity);
slice = preallocatedLEBuf.slice(0, capacity); slice = preallocatedLittleEndianBuffer.slice(0, capacity);
preallocatedLEBufPos = capacity; preallocatedLittleEndianBufferPosition = capacity;
} }
} }
return slice; return slice;

View File

@ -59,8 +59,7 @@ package org.jboss.netty.channel;
* <p> * <p>
* <strong>Caution:</strong> * <strong>Caution:</strong>
* <p> * <p>
* Use the *Later(..) methods of the {@link Channels} class if you want to send an upstream event * 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.
* from a {@link ChannelDownstreamHandler} otherwise you may run into threading issues.
* *
* <h3>State management</h3> * <h3>State management</h3>
* *

View File

@ -71,8 +71,7 @@ import org.jboss.netty.channel.socket.ServerSocketChannel;
* <td>{@code "channelOpen"}</td> * <td>{@code "channelOpen"}</td>
* <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#OPEN OPEN}, value = {@code true})</td> * <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#OPEN OPEN}, value = {@code true})</td>
* <td>a {@link Channel} is open, but not bound nor connected</td> * <td>a {@link Channel} is open, but not bound nor connected</td>
* <td><strong>Be aware that this event is fired from within the Boss-Thread so you should not * <td><strong>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!</strong></td>
* execute any heavy operation in there as it will block the dispatching to other workers!</strong></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@code "channelClosed"}</td> * <td>{@code "channelClosed"}</td>
@ -83,8 +82,7 @@ import org.jboss.netty.channel.socket.ServerSocketChannel;
* <td>{@code "channelBound"}</td> * <td>{@code "channelBound"}</td>
* <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#BOUND BOUND}, value = {@link SocketAddress})</td> * <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#BOUND BOUND}, value = {@link SocketAddress})</td>
* <td>a {@link Channel} is open and bound to a local address, but not connected.</td> * <td>a {@link Channel} is open and bound to a local address, but not connected.</td>
* <td><strong>Be aware that this event is fired from within the Boss-Thread so you should not * <td><strong>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!</strong></td>
* execute any heavy operation in there as it will block the dispatching to other workers!</strong></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@code "channelUnbound"}</td> * <td>{@code "channelUnbound"}</td>
@ -93,11 +91,9 @@ import org.jboss.netty.channel.socket.ServerSocketChannel;
* </tr> * </tr>
* <tr> * <tr>
* <td>{@code "channelConnected"}</td> * <td>{@code "channelConnected"}</td>
* <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#CONNECTED CONNECTED}, value = * <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress})</td>
* {@link SocketAddress})</td>
* <td>a {@link Channel} is open, bound to a local address, and connected to a remote address</td> * <td>a {@link Channel} is open, bound to a local address, and connected to a remote address</td>
* <td><strong>Be aware that this event is fired from within the Boss-Thread so you should not * <td><strong>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!</strong></td>
* execute any heavy operation in there as it will block the dispatching to other workers!</strong></td>
* </tr> * </tr>
* <tr> * <tr>
* <td>{@code "writeComplete"}</td> * <td>{@code "writeComplete"}</td>
@ -157,8 +153,7 @@ import org.jboss.netty.channel.socket.ServerSocketChannel;
* </tr> * </tr>
* <tr> * <tr>
* <td>{@code "connect"}</td> * <td>{@code "connect"}</td>
* <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#CONNECTED CONNECTED}, value = * <td>{@link ChannelStateEvent}<br/>(state = {@link ChannelState#CONNECTED CONNECTED}, value = {@link SocketAddress})</td>
* {@link SocketAddress})</td>
* <td>Connect the {@link Channel} to the specified remote address.</td> * <td>Connect the {@link Channel} to the specified remote address.</td>
* </tr> * </tr>
* <tr> * <tr>

View File

@ -142,7 +142,7 @@ import org.jboss.netty.channel.group.ChannelGroup;
* <pre> * <pre>
* public final class DataServerState { * public final class DataServerState {
* *
* <b>public static final {@link ChannelLocal}&lt;Boolean&gt; loggedIn = new {@link ChannelLocal}&lt;&gt;() { * <b>public static final {@link ChannelLocal}&lt;Boolean&gt; loggedIn = new {@link ChannelLocal}&lt;Boolean&gt;() {
* protected Boolean initialValue(Channel channel) { * protected Boolean initialValue(Channel channel) {
* return false; * return false;
* } * }

View File

@ -48,8 +48,7 @@ public class ChannelLocal<T> implements Iterable<Entry<Channel, T>> {
private final boolean removeOnClose; private final boolean removeOnClose;
/** /**
* Creates a {@link Channel} local variable by calling {@link #ChannelLocal(boolean)} with * Creates a {@link Channel} local variable by calling {@link #ChannelLocal(boolean)} with <code>false</code> as parameter
* <code>false</code> as parameter
*/ */
public ChannelLocal() { public ChannelLocal() {
this(false); this(false);
@ -58,8 +57,7 @@ public class ChannelLocal<T> implements Iterable<Entry<Channel, T>> {
/** /**
* Creates a {@link Channel} local variable. * Creates a {@link Channel} local variable.
* *
* @param removeOnClose if <code>true</code> the {@link ChannelLocal} will remove a * @param removeOnClose if <code>true</code> the {@link ChannelLocal} will remove a {@link Channel} from it own once the {@link Channel} was closed.
* {@link Channel} from it own once the {@link Channel} was closed.
*/ */
public ChannelLocal(boolean removeOnClose) { public ChannelLocal(boolean removeOnClose) {
this.removeOnClose = removeOnClose; this.removeOnClose = removeOnClose;

View File

@ -168,8 +168,7 @@ import org.jboss.netty.handler.ssl.SslHandler;
* {@link ChannelPipeline} pipeline = {@link Channels#pipeline() Channels.pipeline()}; * {@link ChannelPipeline} pipeline = {@link Channels#pipeline() Channels.pipeline()};
* pipeline.addLast("decoder", new MyProtocolDecoder()); * pipeline.addLast("decoder", new MyProtocolDecoder());
* pipeline.addLast("encoder", new MyProtocolEncoder()); * pipeline.addLast("encoder", new MyProtocolEncoder());
* pipeline.addLast("executor", new {@link ExecutionHandler}( * pipeline.addLast("executor", new {@link ExecutionHandler}(new {@link OrderedMemoryAwareThreadPoolExecutor}(16, 1048576, 1048576)));
* new {@link OrderedMemoryAwareThreadPoolExecutor}(16, 1048576, 1048576)));
* pipeline.addLast("handler", new MyBusinessLogicHandler()); * pipeline.addLast("handler", new MyBusinessLogicHandler());
* </pre> * </pre>
* *

View File

@ -29,60 +29,46 @@ import java.net.SocketAddress;
* <th>Direction</th><th>State</th><th>Value</th><th>Meaning</th> * <th>Direction</th><th>State</th><th>Value</th><th>Meaning</th>
* </tr> * </tr>
* <tr> * <tr>
* <td>Upstream</td><td>{@link #OPEN}</td> * <td>Upstream</td><td>{@link #OPEN}</td><td>{@code true}</td><td>The channel is open.</td>
* <td>{@code true}</td><td>The channel is open.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Upstream</td><td>{@link #OPEN}</td> * <td>Upstream</td><td>{@link #OPEN}</td><td>{@code false}</td><td>The channel is closed.</td>
* <td>{@code false}</td><td>The channel is closed.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Upstream</td><td>{@link #BOUND}</td> * <td>Upstream</td><td>{@link #BOUND}</td><td>{@link SocketAddress}</td><td>The channel is bound to a local address.</td>
* <td>{@link SocketAddress}</td><td>The channel is bound to a local address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Upstream</td><td>{@link #BOUND}</td> * <td>Upstream</td><td>{@link #BOUND}</td><td>{@code null}</td><td>The channel is unbound to a local address.</td>
* <td>{@code null}</td><td>The channel is unbound to a local address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Upstream</td><td>{@link #CONNECTED}</td> * <td>Upstream</td><td>{@link #CONNECTED}</td><td>{@link SocketAddress}</td><td>The channel is connected to a remote address.</td>
* <td>{@link SocketAddress}</td><td>The channel is connected to a remote address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Upstream</td><td>{@link #CONNECTED}</td> * <td>Upstream</td><td>{@link #CONNECTED}</td><td>{@code null}</td><td>The channel is disconnected from a remote address.</td>
* <td>{@code null}</td><td>The channel is disconnected from a remote address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Upstream</td><td>{@link #INTEREST_OPS}</td> * <td>Upstream</td><td>{@link #INTEREST_OPS}</td><td>an integer</td><td>The channel interestOps has been changed.</td>
* <td>an integer</td><td>The channel interestOps has been changed.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Downstream</td><td>{@link #OPEN}</td> * <td>Downstream</td><td>{@link #OPEN}</td><td>{@code true}</td><td>N/A</td>
* <td>{@code true}</td><td>N/A</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Downstream</td><td>{@link #OPEN}</td> * <td>Downstream</td><td>{@link #OPEN}</td><td>{@code false}</td><td>Close the channel.</td>
* <td>{@code false}</td><td>Close the channel.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Downstream</td><td>{@link #BOUND}</td> * <td>Downstream</td><td>{@link #BOUND}</td><td>{@link SocketAddress}</td><td>Bind the channel to the specified local address.</td>
* <td>{@link SocketAddress}</td><td>Bind the channel to the specified local address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Downstream</td><td>{@link #BOUND}</td> * <td>Downstream</td><td>{@link #BOUND}</td><td>{@code null}</td><td>Unbind the channel from the current local address.</td>
* <td>{@code null}</td><td>Unbind the channel from the current local address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Downstream</td><td>{@link #CONNECTED}</td> * <td>Downstream</td><td>{@link #CONNECTED}</td><td>{@link SocketAddress}</td><td>Connect the channel to the specified remote address.</td>
* <td>{@link SocketAddress}</td><td>Connect the channel to the specified remote address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Downstream</td><td>{@link #CONNECTED}</td> * <td>Downstream</td><td>{@link #CONNECTED}</td><td>{@code null}</td><td>Disconnect the channel from the current remote address.</td>
* <td>{@code null}</td><td>Disconnect the channel from the current remote address.</td>
* </tr> * </tr>
* <tr> * <tr>
* <td>Downstream</td><td>{@link #INTEREST_OPS}</td> * <td>Downstream</td><td>{@link #INTEREST_OPS}</td><td>an integer</td><td>Change the interestOps of the channel.</td>
* <td>an integer</td><td>Change the interestOps of the channel.</td>
* </tr> * </tr>
* </table> * </table>
* <p> * <p>

View File

@ -52,8 +52,7 @@ import java.net.SocketAddress;
* <p> * <p>
* <strong>Caution:</strong> * <strong>Caution:</strong>
* <p> * <p>
* Use the *Later(..) methods of the {@link Channels} class if you want to send an upstream event * 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.
* from a {@link ChannelDownstreamHandler} otherwise you may run into threading issues.
* *
*/ */
public class SimpleChannelDownstreamHandler implements ChannelDownstreamHandler { public class SimpleChannelDownstreamHandler implements ChannelDownstreamHandler {

View File

@ -147,8 +147,7 @@ public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler {
* Invoked when a {@link Channel} is open, but not bound nor connected. * Invoked when a {@link Channel} is open, but not bound nor connected.
* <br/> * <br/>
* *
* <strong>Be aware that this event is fired from within the Boss-Thread so you should not * <strong>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!</strong>
* execute any heavy operation in there as it will block the dispatching to other workers!</strong>
*/ */
public void channelOpen( public void channelOpen(
ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
@ -160,8 +159,7 @@ public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler {
* but not connected. * but not connected.
* <br/> * <br/>
* *
* <strong>Be aware that this event is fired from within the Boss-Thread so you should not * <strong>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!</strong>
* execute any heavy operation in there as it will block the dispatching to other workers!</strong>
*/ */
public void channelBound( public void channelBound(
ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
@ -173,8 +171,7 @@ public class SimpleChannelUpstreamHandler implements ChannelUpstreamHandler {
* connected to a remote address. * connected to a remote address.
* <br/> * <br/>
* *
* <strong>Be aware that this event is fired from within the Boss-Thread so you should not * <strong>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!</strong>
* execute any heavy operation in there as it will block the dispatching to other workers!</strong>
*/ */
public void channelConnected( public void channelConnected(
ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {

View File

@ -55,9 +55,7 @@ final class DefaultLocalChannel extends AbstractChannel implements LocalChannel
volatile LocalAddress localAddress; volatile LocalAddress localAddress;
volatile LocalAddress remoteAddress; volatile LocalAddress remoteAddress;
DefaultLocalChannel( DefaultLocalChannel(LocalServerChannel parent, ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink, DefaultLocalChannel pairedChannel) {
LocalServerChannel parent, ChannelFactory factory, ChannelPipeline pipeline,
ChannelSink sink, DefaultLocalChannel pairedChannel) {
super(parent, factory, pipeline, sink); super(parent, factory, pipeline, sink);
this.pairedChannel = pairedChannel; this.pairedChannel = pairedChannel;
config = new DefaultChannelConfig(); config = new DefaultChannelConfig();

View File

@ -43,8 +43,8 @@ public class DefaultLocalServerChannelFactory implements LocalServerChannelFacto
/** /**
* Release all the previous created channels. * Release all the previous created channels. This takes care of calling {@link LocalChannelRegistry#unregister(LocalAddress)}
* This takes care of calling {@link LocalChannelRegistry#unregister(LocalAddress)} for each of them. * for each if them.
*/ */
public void releaseExternalResources() { public void releaseExternalResources() {
group.close().awaitUninterruptibly(); group.close().awaitUninterruptibly();

View File

@ -1,58 +1,58 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket; package org.jboss.netty.channel.socket;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.DefaultChannelFuture; import org.jboss.netty.channel.DefaultChannelFuture;
public class ChannelRunnableWrapper extends DefaultChannelFuture implements Runnable { public class ChannelRunnableWrapper extends DefaultChannelFuture implements Runnable {
private final Runnable task; private final Runnable task;
private boolean started; private boolean started;
public ChannelRunnableWrapper(Channel channel, Runnable task) { public ChannelRunnableWrapper(Channel channel, Runnable task) {
super(channel, true); super(channel, true);
this.task = task; this.task = task;
} }
public void run() { public void run() {
synchronized (this) { synchronized (this) {
if (!isCancelled()) { if (!isCancelled()) {
started = true; started = true;
} else { } else {
return; return;
} }
} }
try { try {
task.run(); task.run();
setSuccess(); setSuccess();
} catch (Throwable t) { } catch (Throwable t) {
setFailure(t); setFailure(t);
} }
} }
@Override @Override
public synchronized boolean cancel() { public synchronized boolean cancel() {
if (started) { if (started) {
return false; return false;
} }
return super.cancel(); return super.cancel();
} }
} }

View File

@ -15,9 +15,9 @@
*/ */
package org.jboss.netty.channel.socket; package org.jboss.netty.channel.socket;
import java.net.DatagramSocket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.StandardSocketOptions;
import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.ChannelConfig;
import org.jboss.netty.channel.FixedReceiveBufferSizePredictor; import org.jboss.netty.channel.FixedReceiveBufferSizePredictor;
@ -49,11 +49,9 @@ import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory;
* </tr><tr> * </tr><tr>
* <td>{@code "receiveBufferSize"}</td><td>{@link #setReceiveBufferSize(int)}</td> * <td>{@code "receiveBufferSize"}</td><td>{@link #setReceiveBufferSize(int)}</td>
* </tr><tr> * </tr><tr>
* <td>{@code "receiveBufferSizePredictor"}</td> * <td>{@code "receiveBufferSizePredictor"}</td><td>{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)}</td>
* <td>{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)}</td>
* </tr><tr> * </tr><tr>
* <td>{@code "receiveBufferSizePredictorFactory"}</td> * <td>{@code "receiveBufferSizePredictorFactory"}</td><td>{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)}</td>
* <td>{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)}</td>
* </tr><tr> * </tr><tr>
* <td>{@code "sendBufferSize"}</td><td>{@link #setSendBufferSize(int)}</td> * <td>{@code "sendBufferSize"}</td><td>{@link #setSendBufferSize(int)}</td>
* </tr><tr> * </tr><tr>
@ -66,62 +64,64 @@ import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory;
public interface DatagramChannelConfig extends ChannelConfig { public interface DatagramChannelConfig extends ChannelConfig {
/** /**
* Gets the {@link StandardSocketOptions#SO_SNDBUF} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_SNDBUF}</a> option.
*/ */
int getSendBufferSize(); int getSendBufferSize();
/** /**
* Sets the {@link StandardSocketOptions#SO_SNDBUF} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_SNDBUF}</a> option.
*/ */
void setSendBufferSize(int sendBufferSize); void setSendBufferSize(int sendBufferSize);
/** /**
* Gets the {@link StandardSocketOptions#SO_RCVBUF} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_RCVBUF}</a> option.
*/ */
int getReceiveBufferSize(); int getReceiveBufferSize();
/** /**
* Sets the {@link StandardSocketOptions#SO_RCVBUF} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_RCVBUF}</a> option.
*/ */
void setReceiveBufferSize(int receiveBufferSize); void setReceiveBufferSize(int receiveBufferSize);
/** /**
* Gets the {@link StandardSocketOptions#IP_TOS} option. * Gets the traffic class.
*/ */
int getTrafficClass(); int getTrafficClass();
/** /**
* Gets the {@link StandardSocketOptions#IP_TOS} option. * Sets the traffic class as specified in {@link DatagramSocket#setTrafficClass(int)}.
*/ */
void setTrafficClass(int trafficClass); void setTrafficClass(int trafficClass);
/** /**
* Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_REUSEADDR}</a> option.
*/ */
boolean isReuseAddress(); boolean isReuseAddress();
/** /**
* Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_REUSEADDR}</a> option.
*/ */
void setReuseAddress(boolean reuseAddress); void setReuseAddress(boolean reuseAddress);
/** /**
* Gets the {@link StandardSocketOptions#SO_BROADCAST} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_BROADCAST}</a> option.
*/ */
boolean isBroadcast(); boolean isBroadcast();
/** /**
* Sets the {@link StandardSocketOptions#SO_BROADCAST} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_BROADCAST}</a> option.
*/ */
void setBroadcast(boolean broadcast); void setBroadcast(boolean broadcast);
/** /**
* Gets the {@link StandardSocketOptions#IP_MULTICAST_LOOP} option. * Gets the setting for local loopback of multicast datagrams.
*
* @return {@code true} if and only if the loopback mode has been disabled
*/ */
boolean isLoopbackModeDisabled(); boolean isLoopbackModeDisabled();
/** /**
* Sets the {@link StandardSocketOptions#IP_MULTICAST_LOOP} option. * Sets the setting for local loopback of multicast datagrams.
* *
* @param loopbackModeDisabled * @param loopbackModeDisabled
* {@code true} if and only if the loopback mode has been disabled * {@code true} if and only if the loopback mode has been disabled
@ -129,12 +129,14 @@ public interface DatagramChannelConfig extends ChannelConfig {
void setLoopbackModeDisabled(boolean loopbackModeDisabled); void setLoopbackModeDisabled(boolean loopbackModeDisabled);
/** /**
* Gets the {@link StandardSocketOptions#IP_MULTICAST_TTL} option. * Gets the default time-to-live for multicast packets sent out on the
* socket.
*/ */
int getTimeToLive(); int getTimeToLive();
/** /**
* Sets the {@link StandardSocketOptions#IP_MULTICAST_TTL} option. * Sets the default time-to-live for multicast packets sent out on the
* {@link DatagramChannel} in order to control the scope of the multicasts.
*/ */
void setTimeToLive(int ttl); void setTimeToLive(int ttl);
@ -149,12 +151,14 @@ public interface DatagramChannelConfig extends ChannelConfig {
void setInterface(InetAddress interfaceAddress); void setInterface(InetAddress interfaceAddress);
/** /**
* Gets the {@link StandardSocketOptions#IP_MULTICAST_IF} option. * Gets the network interface for outgoing multicast datagrams sent on
* the {@link DatagramChannel}.
*/ */
NetworkInterface getNetworkInterface(); NetworkInterface getNetworkInterface();
/** /**
* Sets the {@link StandardSocketOptions#IP_MULTICAST_IF} option. * Sets the network interface for outgoing multicast datagrams sent on
* the {@link DatagramChannel}.
*/ */
void setNetworkInterface(NetworkInterface networkInterface); void setNetworkInterface(NetworkInterface networkInterface);

View File

@ -16,7 +16,6 @@
package org.jboss.netty.channel.socket; package org.jboss.netty.channel.socket;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.StandardSocketOptions;
import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.ChannelConfig;
@ -56,22 +55,22 @@ public interface ServerSocketChannelConfig extends ChannelConfig {
void setBacklog(int backlog); void setBacklog(int backlog);
/** /**
* Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_REUSEADDR}</a> option.
*/ */
boolean isReuseAddress(); boolean isReuseAddress();
/** /**
* Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_REUSEADDR}</a> option.
*/ */
void setReuseAddress(boolean reuseAddress); void setReuseAddress(boolean reuseAddress);
/** /**
* Gets the {@link StandardSocketOptions#SO_RCVBUF} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_RCVBUF}</a> option.
*/ */
int getReceiveBufferSize(); int getReceiveBufferSize();
/** /**
* Sets the {@link StandardSocketOptions#SO_RCVBUF} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_RCVBUF}</a> option.
*/ */
void setReceiveBufferSize(int receiveBufferSize); void setReceiveBufferSize(int receiveBufferSize);

View File

@ -16,7 +16,6 @@
package org.jboss.netty.channel.socket; package org.jboss.netty.channel.socket;
import java.net.Socket; import java.net.Socket;
import java.net.StandardSocketOptions;
import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.ChannelConfig;
@ -51,72 +50,72 @@ import org.jboss.netty.channel.ChannelConfig;
public interface SocketChannelConfig extends ChannelConfig { public interface SocketChannelConfig extends ChannelConfig {
/** /**
* Gets the {@link StandardSocketOptions#TCP_NODELAY} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_TCPNODELAY}</a> option.
*/ */
boolean isTcpNoDelay(); boolean isTcpNoDelay();
/** /**
* Sets the {@link StandardSocketOptions#TCP_NODELAY} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_TCPNODELAY}</a> option.
*/ */
void setTcpNoDelay(boolean tcpNoDelay); void setTcpNoDelay(boolean tcpNoDelay);
/** /**
* Gets the {@link StandardSocketOptions#SO_LINGER} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_LINGER}</a> option.
*/ */
int getSoLinger(); int getSoLinger();
/** /**
* Sets the {@link StandardSocketOptions#SO_LINGER} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_LINGER}</a> option.
*/ */
void setSoLinger(int soLinger); void setSoLinger(int soLinger);
/** /**
* Gets the {@link StandardSocketOptions#SO_SNDBUF} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_SNDBUF}</a> option.
*/ */
int getSendBufferSize(); int getSendBufferSize();
/** /**
* Sets the {@link StandardSocketOptions#SO_SNDBUF} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_SNDBUF}</a> option.
*/ */
void setSendBufferSize(int sendBufferSize); void setSendBufferSize(int sendBufferSize);
/** /**
* Gets the {@link StandardSocketOptions#SO_RCVBUF} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_RCVBUF}</a> option.
*/ */
int getReceiveBufferSize(); int getReceiveBufferSize();
/** /**
* Sets the {@link StandardSocketOptions#SO_RCVBUF} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_RCVBUF}</a> option.
*/ */
void setReceiveBufferSize(int receiveBufferSize); void setReceiveBufferSize(int receiveBufferSize);
/** /**
* Gets the {@link StandardSocketOptions#SO_KEEPALIVE} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_KEEPALIVE}</a> option.
*/ */
boolean isKeepAlive(); boolean isKeepAlive();
/** /**
* Sets the {@link StandardSocketOptions#SO_KEEPALIVE} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_KEEPALIVE}</a> option.
*/ */
void setKeepAlive(boolean keepAlive); void setKeepAlive(boolean keepAlive);
/** /**
* Gets the {@link StandardSocketOptions#IP_TOS} option. * Gets the traffic class.
*/ */
int getTrafficClass(); int getTrafficClass();
/** /**
* Sets the {@link StandardSocketOptions#IP_TOS} option. * Sets the traffic class as specified in {@link Socket#setTrafficClass(int)}.
*/ */
void setTrafficClass(int trafficClass); void setTrafficClass(int trafficClass);
/** /**
* Gets the {@link StandardSocketOptions#SO_REUSEADDR} option. * Gets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_REUSEADDR}</a> option.
*/ */
boolean isReuseAddress(); boolean isReuseAddress();
/** /**
* Sets the {@link StandardSocketOptions#SO_REUSEADDR} option. * Sets the <a href="http://java.sun.com/javase/6/docs/technotes/guides/net/socketOpt.html">{@code SO_REUSEADDR}</a> option.
*/ */
void setReuseAddress(boolean reuseAddress); void setReuseAddress(boolean reuseAddress);

View File

@ -1,33 +1,33 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket; package org.jboss.netty.channel.socket;
/** /**
* A {@link Worker} is responsible to dispatch IO operations * A {@link Worker} is responsible to dispatch IO operations
* *
*/ */
public interface Worker extends Runnable { public interface Worker extends Runnable {
/** /**
* Execute the given {@link Runnable} in the IO-Thread. This may be now or * Execute the given {@link Runnable} in the IO-Thread. This may be now or
* later once the IO-Thread do some other work. * later once the IO-Thread do some other work.
* *
* @param task * @param task
* the {@link Runnable} to execute * the {@link Runnable} to execute
*/ */
void executeInIoThread(Runnable task); void executeInIoThread(Runnable task);
} }

View File

@ -1,370 +1,368 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import static org.jboss.netty.channel.Channels.*; import static org.jboss.netty.channel.Channels.*;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.channels.SelectableChannel; import java.nio.channels.SelectableChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.AbstractChannel; import org.jboss.netty.channel.AbstractChannel;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelSink; import org.jboss.netty.channel.ChannelSink;
import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer; import org.jboss.netty.channel.socket.nio.SocketSendBufferPool.SendBuffer;
import org.jboss.netty.util.internal.QueueFactory; import org.jboss.netty.util.internal.QueueFactory;
import org.jboss.netty.util.internal.ThreadLocalBoolean; import org.jboss.netty.util.internal.ThreadLocalBoolean;
abstract class AbstractNioChannel<C extends SelectableChannel & WritableByteChannel> extends AbstractChannel { abstract class AbstractNioChannel<C extends SelectableChannel & WritableByteChannel> extends AbstractChannel {
/** /**
* The {@link AbstractNioWorker}. * The {@link AbstractNioWorker}.
*/ */
final AbstractNioWorker worker; final AbstractNioWorker worker;
/** /**
* Monitor object to synchronize access to InterestedOps. * Monitor object to synchronize access to InterestedOps.
*/ */
final Object interestOpsLock = new Object(); final Object interestOpsLock = new Object();
/** /**
* Monitor object for synchronizing access to the {@link WriteRequestQueue}. * Monitor object for synchronizing access to the {@link WriteRequestQueue}.
*/ */
final Object writeLock = new Object(); final Object writeLock = new Object();
/** /**
* WriteTask that performs write operations. * WriteTask that performs write operations.
*/ */
final Runnable writeTask = new WriteTask(); final Runnable writeTask = new WriteTask();
/** /**
* Indicates if there is a {@link WriteTask} in the task queue. * Indicates if there is a {@link WriteTask} in the task queue.
*/ */
final AtomicBoolean writeTaskInTaskQueue = new AtomicBoolean(); final AtomicBoolean writeTaskInTaskQueue = new AtomicBoolean();
/** /**
* Queue of write {@link MessageEvent}s. * Queue of write {@link MessageEvent}s.
*/ */
final Queue<MessageEvent> writeBufferQueue = new WriteRequestQueue(); final Queue<MessageEvent> writeBufferQueue = new WriteRequestQueue();
/** /**
* Keeps track of the number of bytes that the {@link WriteRequestQueue} currently * Keeps track of the number of bytes that the {@link WriteRequestQueue} currently
* contains. * contains.
*/ */
final AtomicInteger writeBufferSize = new AtomicInteger(); final AtomicInteger writeBufferSize = new AtomicInteger();
/** /**
* Keeps track of the highWaterMark. * Keeps track of the highWaterMark.
*/ */
final AtomicInteger highWaterMarkCounter = new AtomicInteger(); final AtomicInteger highWaterMarkCounter = new AtomicInteger();
/** /**
* The current write {@link MessageEvent} * The current write {@link MessageEvent}
*/ */
MessageEvent currentWriteEvent; MessageEvent currentWriteEvent;
SendBuffer currentWriteBuffer; SendBuffer currentWriteBuffer;
/** /**
* Boolean that indicates that write operation is in progress. * Boolean that indicates that write operation is in progress.
*/ */
boolean inWriteNowLoop; boolean inWriteNowLoop;
boolean writeSuspended; boolean writeSuspended;
private volatile InetSocketAddress localAddress; private volatile InetSocketAddress localAddress;
volatile InetSocketAddress remoteAddress; volatile InetSocketAddress remoteAddress;
final C channel; final C channel;
protected AbstractNioChannel( protected AbstractNioChannel(Integer id, Channel parent, ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink, AbstractNioWorker worker, C ch) {
Integer id, Channel parent, ChannelFactory factory, ChannelPipeline pipeline, super(id, parent, factory, pipeline, sink);
ChannelSink sink, AbstractNioWorker worker, C ch) { this.worker = worker;
super(id, parent, factory, pipeline, sink); this.channel = ch;
this.worker = worker; }
this.channel = ch;
} protected AbstractNioChannel(
Channel parent, ChannelFactory factory,
protected AbstractNioChannel( ChannelPipeline pipeline, ChannelSink sink, AbstractNioWorker worker, C ch) {
Channel parent, ChannelFactory factory, super(parent, factory, pipeline, sink);
ChannelPipeline pipeline, ChannelSink sink, AbstractNioWorker worker, C ch) { this.worker = worker;
super(parent, factory, pipeline, sink); this.channel = ch;
this.worker = worker; }
this.channel = ch;
} /**
* Return the {@link AbstractNioWorker} that handle the IO of the
/** * {@link AbstractNioChannel}
* Return the {@link AbstractNioWorker} that handle the IO of the *
* {@link AbstractNioChannel} * @return worker
* */
* @return worker public AbstractNioWorker getWorker() {
*/ return worker;
public AbstractNioWorker getWorker() { }
return worker;
} public InetSocketAddress getLocalAddress() {
InetSocketAddress localAddress = this.localAddress;
public InetSocketAddress getLocalAddress() { if (localAddress == null) {
InetSocketAddress localAddress = this.localAddress; try {
if (localAddress == null) { this.localAddress = localAddress = getLocalSocketAddress();
try { } catch (Throwable t) {
this.localAddress = localAddress = getLocalSocketAddress(); // Sometimes fails on a closed socket in Windows.
} catch (Throwable t) { return null;
// Sometimes fails on a closed socket in Windows. }
return null; }
} return localAddress;
} }
return localAddress;
} public InetSocketAddress getRemoteAddress() {
InetSocketAddress remoteAddress = this.remoteAddress;
public InetSocketAddress getRemoteAddress() { if (remoteAddress == null) {
InetSocketAddress remoteAddress = this.remoteAddress; try {
if (remoteAddress == null) { this.remoteAddress = remoteAddress =
try { getRemoteSocketAddress();
this.remoteAddress = remoteAddress = } catch (Throwable t) {
getRemoteSocketAddress(); // Sometimes fails on a closed socket in Windows.
} catch (Throwable t) { return null;
// Sometimes fails on a closed socket in Windows. }
return null; }
} return remoteAddress;
} }
return remoteAddress;
} public abstract NioChannelConfig getConfig();
public abstract NioChannelConfig getConfig(); int getRawInterestOps() {
return super.getInterestOps();
int getRawInterestOps() { }
return super.getInterestOps();
} void setRawInterestOpsNow(int interestOps) {
super.setInterestOpsNow(interestOps);
void setRawInterestOpsNow(int interestOps) { }
super.setInterestOpsNow(interestOps);
}
@Override
public int getInterestOps() {
@Override if (!isOpen()) {
public int getInterestOps() { return Channel.OP_WRITE;
if (!isOpen()) { }
return Channel.OP_WRITE;
} int interestOps = getRawInterestOps();
int writeBufferSize = this.writeBufferSize.get();
int interestOps = getRawInterestOps(); if (writeBufferSize != 0) {
int writeBufferSize = this.writeBufferSize.get(); if (highWaterMarkCounter.get() > 0) {
if (writeBufferSize != 0) { int lowWaterMark = getConfig().getWriteBufferLowWaterMark();
if (highWaterMarkCounter.get() > 0) { if (writeBufferSize >= lowWaterMark) {
int lowWaterMark = getConfig().getWriteBufferLowWaterMark(); interestOps |= Channel.OP_WRITE;
if (writeBufferSize >= lowWaterMark) { } else {
interestOps |= Channel.OP_WRITE; interestOps &= ~Channel.OP_WRITE;
} else { }
interestOps &= ~Channel.OP_WRITE; } else {
} int highWaterMark = getConfig().getWriteBufferHighWaterMark();
} else { if (writeBufferSize >= highWaterMark) {
int highWaterMark = getConfig().getWriteBufferHighWaterMark(); interestOps |= Channel.OP_WRITE;
if (writeBufferSize >= highWaterMark) { } else {
interestOps |= Channel.OP_WRITE; interestOps &= ~Channel.OP_WRITE;
} else { }
interestOps &= ~Channel.OP_WRITE; }
} } else {
} interestOps &= ~Channel.OP_WRITE;
} else { }
interestOps &= ~Channel.OP_WRITE;
} return interestOps;
}
return interestOps;
} @Override
protected boolean setClosed() {
@Override return super.setClosed();
protected boolean setClosed() { }
return super.setClosed();
} abstract InetSocketAddress getLocalSocketAddress() throws Exception;
abstract InetSocketAddress getLocalSocketAddress() throws Exception; abstract InetSocketAddress getRemoteSocketAddress() throws Exception;
abstract InetSocketAddress getRemoteSocketAddress() throws Exception; private final class WriteRequestQueue implements BlockingQueue<MessageEvent> {
private final ThreadLocalBoolean notifying = new ThreadLocalBoolean();
private final class WriteRequestQueue implements BlockingQueue<MessageEvent> {
private final ThreadLocalBoolean notifying = new ThreadLocalBoolean(); private final BlockingQueue<MessageEvent> queue;
private final BlockingQueue<MessageEvent> queue; public WriteRequestQueue() {
this.queue = QueueFactory.createQueue(MessageEvent.class);
public WriteRequestQueue() { }
this.queue = QueueFactory.createQueue(MessageEvent.class);
} public MessageEvent remove() {
return queue.remove();
public MessageEvent remove() { }
return queue.remove();
} public MessageEvent element() {
return queue.element();
public MessageEvent element() { }
return queue.element();
} public MessageEvent peek() {
return queue.peek();
public MessageEvent peek() { }
return queue.peek();
} public int size() {
return queue.size();
public int size() { }
return queue.size();
} public boolean isEmpty() {
return queue.isEmpty();
public boolean isEmpty() { }
return queue.isEmpty();
} public Iterator<MessageEvent> iterator() {
return queue.iterator();
public Iterator<MessageEvent> iterator() { }
return queue.iterator();
} public Object[] toArray() {
return queue.toArray();
public Object[] toArray() { }
return queue.toArray();
} public <T> T[] toArray(T[] a) {
return queue.toArray(a);
public <T> T[] toArray(T[] a) { }
return queue.toArray(a);
} public boolean containsAll(Collection<?> c) {
return queue.containsAll(c);
public boolean containsAll(Collection<?> c) { }
return queue.containsAll(c);
} public boolean addAll(Collection<? extends MessageEvent> c) {
return queue.addAll(c);
public boolean addAll(Collection<? extends MessageEvent> c) { }
return queue.addAll(c);
} public boolean removeAll(Collection<?> c) {
return queue.removeAll(c);
public boolean removeAll(Collection<?> c) { }
return queue.removeAll(c);
} public boolean retainAll(Collection<?> c) {
return queue.retainAll(c);
public boolean retainAll(Collection<?> c) { }
return queue.retainAll(c);
} public void clear() {
queue.clear();
public void clear() { }
queue.clear();
} public boolean add(MessageEvent e) {
return queue.add(e);
public boolean add(MessageEvent e) { }
return queue.add(e);
} public void put(MessageEvent e) throws InterruptedException {
queue.put(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 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 take() throws InterruptedException { }
return queue.take();
} public MessageEvent poll(long timeout, TimeUnit unit) throws InterruptedException {
return queue.poll(timeout, unit);
public MessageEvent poll(long timeout, TimeUnit unit) throws InterruptedException { }
return queue.poll(timeout, unit);
} public int remainingCapacity() {
return queue.remainingCapacity();
public int remainingCapacity() { }
return queue.remainingCapacity();
} public boolean remove(Object o) {
return queue.remove(o);
public boolean remove(Object o) { }
return queue.remove(o);
} public boolean contains(Object o) {
return queue.contains(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) { }
return queue.drainTo(c);
} public int drainTo(Collection<? super MessageEvent> c, int maxElements) {
return queue.drainTo(c, maxElements);
public int drainTo(Collection<? super MessageEvent> c, int maxElements) { }
return queue.drainTo(c, maxElements);
} public boolean offer(MessageEvent e) {
boolean success = queue.offer(e);
public boolean offer(MessageEvent e) { assert success;
boolean success = queue.offer(e);
assert success; int messageSize = getMessageSize(e);
int newWriteBufferSize = writeBufferSize.addAndGet(messageSize);
int messageSize = getMessageSize(e); int highWaterMark = getConfig().getWriteBufferHighWaterMark();
int newWriteBufferSize = writeBufferSize.addAndGet(messageSize);
int highWaterMark = getConfig().getWriteBufferHighWaterMark(); if (newWriteBufferSize >= highWaterMark) {
if (newWriteBufferSize - messageSize < highWaterMark) {
if (newWriteBufferSize >= highWaterMark) { highWaterMarkCounter.incrementAndGet();
if (newWriteBufferSize - messageSize < highWaterMark) { if (!notifying.get()) {
highWaterMarkCounter.incrementAndGet(); notifying.set(Boolean.TRUE);
if (!notifying.get()) { fireChannelInterestChanged(AbstractNioChannel.this);
notifying.set(Boolean.TRUE); notifying.set(Boolean.FALSE);
fireChannelInterestChanged(AbstractNioChannel.this); }
notifying.set(Boolean.FALSE); }
} }
} return true;
} }
return true;
} public MessageEvent poll() {
MessageEvent e = queue.poll();
public MessageEvent poll() { if (e != null) {
MessageEvent e = queue.poll(); int messageSize = getMessageSize(e);
if (e != null) { int newWriteBufferSize = writeBufferSize.addAndGet(-messageSize);
int messageSize = getMessageSize(e); int lowWaterMark = getConfig().getWriteBufferLowWaterMark();
int newWriteBufferSize = writeBufferSize.addAndGet(-messageSize);
int lowWaterMark = getConfig().getWriteBufferLowWaterMark(); if (newWriteBufferSize == 0 || newWriteBufferSize < lowWaterMark) {
if (newWriteBufferSize + messageSize >= lowWaterMark) {
if (newWriteBufferSize == 0 || newWriteBufferSize < lowWaterMark) { highWaterMarkCounter.decrementAndGet();
if (newWriteBufferSize + messageSize >= lowWaterMark) { if (isConnected() && !notifying.get()) {
highWaterMarkCounter.decrementAndGet(); notifying.set(Boolean.TRUE);
if (isConnected() && !notifying.get()) { fireChannelInterestChanged(AbstractNioChannel.this);
notifying.set(Boolean.TRUE); notifying.set(Boolean.FALSE);
fireChannelInterestChanged(AbstractNioChannel.this); }
notifying.set(Boolean.FALSE); }
} }
} }
} return e;
} }
return e;
} private int getMessageSize(MessageEvent e) {
Object m = e.getMessage();
private int getMessageSize(MessageEvent e) { if (m instanceof ChannelBuffer) {
Object m = e.getMessage(); return ((ChannelBuffer) m).readableBytes();
if (m instanceof ChannelBuffer) { }
return ((ChannelBuffer) m).readableBytes(); return 0;
} }
return 0; }
}
} private final class WriteTask implements Runnable {
private final class WriteTask implements Runnable { WriteTask() {
}
WriteTask() {
} public void run() {
writeTaskInTaskQueue.set(false);
public void run() { worker.writeFromTaskLoop(AbstractNioChannel.this);
writeTaskInTaskQueue.set(false); }
worker.writeFromTaskLoop(AbstractNioChannel.this); }
}
} }
}

View File

@ -1,52 +1,52 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import org.jboss.netty.channel.AbstractChannelSink; import org.jboss.netty.channel.AbstractChannelSink;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.socket.ChannelRunnableWrapper; import org.jboss.netty.channel.socket.ChannelRunnableWrapper;
public abstract class AbstractNioChannelSink extends AbstractChannelSink { public abstract class AbstractNioChannelSink extends AbstractChannelSink {
@Override @Override
public ChannelFuture execute(ChannelPipeline pipeline, final Runnable task) { public ChannelFuture execute(ChannelPipeline pipeline, final Runnable task) {
Channel ch = pipeline.getChannel(); Channel ch = pipeline.getChannel();
if (ch instanceof AbstractNioChannel<?>) { if (ch instanceof AbstractNioChannel<?>) {
AbstractNioChannel<?> channel = (AbstractNioChannel<?>) ch; AbstractNioChannel<?> channel = (AbstractNioChannel<?>) ch;
ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task); ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task);
channel.worker.executeInIoThread(wrapper); channel.worker.executeInIoThread(wrapper);
return wrapper; return wrapper;
} }
return super.execute(pipeline, task); return super.execute(pipeline, task);
} }
@Override @Override
protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) { protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) {
Channel channel = event.getChannel(); Channel channel = event.getChannel();
boolean fireLater = false; boolean fireLater = false;
if (channel instanceof AbstractNioChannel<?>) { if (channel instanceof AbstractNioChannel<?>) {
fireLater = !AbstractNioWorker.isIoThread((AbstractNioChannel<?>) channel); fireLater = !AbstractNioWorker.isIoThread((AbstractNioChannel<?>) channel);
} }
return fireLater; return fireLater;
} }
} }

View File

@ -1,85 +1,83 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.socket.Worker; import org.jboss.netty.channel.socket.Worker;
import org.jboss.netty.util.ExternalResourceReleasable; import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.internal.ExecutorUtil; import org.jboss.netty.util.internal.ExecutorUtil;
/** /**
* Abstract base class for {@link WorkerPool} implementations that create the {@link Worker}'s * Abstract base class for {@link WorkerPool} implementations that create the {@link Worker}'s up-front and return them in a "fair" fashion when calling
* up-front and return them in a "fair" fashion when calling {@link #nextWorker()} * {@link #nextWorker()}
*/ *
public abstract class AbstractNioWorkerPool<E extends AbstractNioWorker> */
implements WorkerPool<E>, ExternalResourceReleasable { public abstract class AbstractNioWorkerPool<E extends AbstractNioWorker> implements WorkerPool<E> , ExternalResourceReleasable {
private final AbstractNioWorker[] workers; private final AbstractNioWorker[] workers;
private final AtomicInteger workerIndex = new AtomicInteger(); private final AtomicInteger workerIndex = new AtomicInteger();
private final Executor workerExecutor; private final Executor workerExecutor;
/** /**
* Create a new instance * Create a new instance
* *
* @param workerExecutor the {@link Executor} to use for the {@link Worker}'s * @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 * @param allowShutdownOnIdle allow the {@link Worker}'s to shutdown when there is not {@link Channel} is registered with it
* {@link Channel} is registered with it * @param workerCount the count of {@link Worker}'s to create
* @param workerCount the count of {@link Worker}'s to create */
*/ AbstractNioWorkerPool(Executor workerExecutor, int workerCount, boolean allowShutDownOnIdle) {
AbstractNioWorkerPool(Executor workerExecutor, int workerCount, boolean allowShutDownOnIdle) { if (workerExecutor == null) {
if (workerExecutor == null) { throw new NullPointerException("workerExecutor");
throw new NullPointerException("workerExecutor"); }
} if (workerCount <= 0) {
if (workerCount <= 0) { throw new IllegalArgumentException(
throw new IllegalArgumentException( "workerCount (" + workerCount + ") " +
"workerCount (" + workerCount + ") " + "must be a positive integer.");
"must be a positive integer."); }
} workers = new AbstractNioWorker[workerCount];
workers = new AbstractNioWorker[workerCount];
for (int i = 0; i < workers.length; i++) {
for (int i = 0; i < workers.length; i++) { workers[i] = createWorker(workerExecutor, allowShutDownOnIdle);
workers[i] = createWorker(workerExecutor, allowShutDownOnIdle); }
} this.workerExecutor = workerExecutor;
this.workerExecutor = workerExecutor;
}
}
/**
/** * Create a new {@link Worker} which uses the given {@link Executor} to service IO
* Create a new {@link Worker} which uses the given {@link Executor} to service IO *
* *
* * @param executor the {@link Executor} to use
* @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
* @param allowShutdownOnIdle allow the {@link Worker} to shutdown when there is not * @return worker the new {@link Worker}
* {@link Channel} is registered with it */
* @return worker the new {@link Worker} protected abstract E createWorker(Executor executor, boolean allowShutdownOnIdle);
*/
protected abstract E createWorker(Executor executor, boolean allowShutdownOnIdle); @SuppressWarnings("unchecked")
public E nextWorker() {
@SuppressWarnings("unchecked") return (E) workers[Math.abs(workerIndex.getAndIncrement() % workers.length)];
public E nextWorker() { }
return (E) workers[Math.abs(workerIndex.getAndIncrement() % workers.length)];
}
public void releaseExternalResources() {
ExecutorUtil.terminate(workerExecutor);
public void releaseExternalResources() { }
ExecutorUtil.terminate(workerExecutor);
} }
}

View File

@ -1,82 +1,82 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelConfig; import org.jboss.netty.channel.ChannelConfig;
/** /**
* Special {@link ChannelConfig} sub-type which offers extra methods which are useful for NIO. * Special {@link ChannelConfig} sub-type which offers extra methods which are useful for NIO.
* *
*/ */
public interface NioChannelConfig extends ChannelConfig { public interface NioChannelConfig extends ChannelConfig {
/** /**
* Returns the high water mark of the write buffer. If the number of bytes * 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()} * queued in the write buffer exceeds this value, {@link Channel#isWritable()}
* will start to return {@code true}. * will start to return {@code true}.
*/ */
int getWriteBufferHighWaterMark(); int getWriteBufferHighWaterMark();
/** /**
* Sets the high water mark of the write buffer. If the number of bytes * 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()} * queued in the write buffer exceeds this value, {@link Channel#isWritable()}
* will start to return {@code true}. * will start to return {@code true}.
*/ */
void setWriteBufferHighWaterMark(int writeBufferHighWaterMark); void setWriteBufferHighWaterMark(int writeBufferHighWaterMark);
/** /**
* Returns the low water mark of the write buffer. Once the number of bytes * Returns the low water mark of the write buffer. Once the number of bytes
* queued in the write buffer exceeded the * queued in the write buffer exceeded the
* {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then
* dropped down below this value, {@link Channel#isWritable()} will return * dropped down below this value, {@link Channel#isWritable()} will return
* {@code false} again. * {@code false} again.
*/ */
int getWriteBufferLowWaterMark(); int getWriteBufferLowWaterMark();
/** /**
* Sets the low water mark of the write buffer. Once the number of bytes * Sets the low water mark of the write buffer. Once the number of bytes
* queued in the write buffer exceeded the * queued in the write buffer exceeded the
* {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then * {@linkplain #setWriteBufferHighWaterMark(int) high water mark} and then
* dropped down below this value, {@link Channel#isWritable()} will return * dropped down below this value, {@link Channel#isWritable()} will return
* {@code false} again. * {@code false} again.
*/ */
void setWriteBufferLowWaterMark(int writeBufferLowWaterMark); void setWriteBufferLowWaterMark(int writeBufferLowWaterMark);
/** /**
* Returns the maximum loop count for a write operation until * Returns the maximum loop count for a write operation until
* {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value.
* It is similar to what a spin lock is used for in concurrency programming. * It is similar to what a spin lock is used for in concurrency programming.
* It improves memory utilization and write throughput depending on * It improves memory utilization and write throughput depending on
* the platform that JVM runs on. The default value is {@code 16}. * the platform that JVM runs on. The default value is {@code 16}.
*/ */
int getWriteSpinCount(); int getWriteSpinCount();
/** /**
* Sets the maximum loop count for a write operation until * Sets the maximum loop count for a write operation until
* {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value. * {@link WritableByteChannel#write(ByteBuffer)} returns a non-zero value.
* It is similar to what a spin lock is used for in concurrency programming. * It is similar to what a spin lock is used for in concurrency programming.
* It improves memory utilization and write throughput depending on * It improves memory utilization and write throughput depending on
* the platform that JVM runs on. The default value is {@code 16}. * the platform that JVM runs on. The default value is {@code 16}.
* *
* @throws IllegalArgumentException * @throws IllegalArgumentException
* if the specified value is {@code 0} or less than {@code 0} * if the specified value is {@code 0} or less than {@code 0}
*/ */
void setWriteSpinCount(int writeSpinCount); void setWriteSpinCount(int writeSpinCount);
} }

View File

@ -88,8 +88,7 @@ public class NioClientSocketChannelFactory implements ClientSocketChannelFactory
private final NioClientSocketPipelineSink sink; private final NioClientSocketPipelineSink sink;
/** /**
* Creates a new {@link NioClientSocketChannelFactory} which uses {@link Executors#newCachedThreadPool()} * Creates a new {@link NioClientSocketChannelFactory} which uses {@link Executors#newCachedThreadPool()} for the worker and boss executors.
* for the worker and boss executors.
* *
* See {@link #NioClientSocketChannelFactory(Executor, Executor)} * See {@link #NioClientSocketChannelFactory(Executor, Executor)}
*/ */

View File

@ -130,8 +130,7 @@ public final class NioDatagramChannel extends AbstractNioChannel<DatagramChannel
public ChannelFuture joinGroup(InetAddress multicastAddress) { public ChannelFuture joinGroup(InetAddress multicastAddress) {
try { try {
return joinGroup( return joinGroup(multicastAddress, NetworkInterface.getByInetAddress(getLocalAddress().getAddress()), null);
multicastAddress, NetworkInterface.getByInetAddress(getLocalAddress().getAddress()), null);
} catch (SocketException e) { } catch (SocketException e) {
return Channels.failedFuture(this, e); return Channels.failedFuture(this, e);
} }
@ -145,8 +144,7 @@ public final class NioDatagramChannel extends AbstractNioChannel<DatagramChannel
/** /**
* Joins the specified multicast group at the specified interface using the specified source. * Joins the specified multicast group at the specified interface using the specified source.
*/ */
public ChannelFuture joinGroup( public ChannelFuture joinGroup(InetAddress multicastAddress, NetworkInterface networkInterface, InetAddress source) {
InetAddress multicastAddress, NetworkInterface networkInterface, InetAddress source) {
if (DetectionUtil.javaVersion() < 7) { if (DetectionUtil.javaVersion() < 7) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} else { } else {
@ -187,8 +185,7 @@ public final class NioDatagramChannel extends AbstractNioChannel<DatagramChannel
public ChannelFuture leaveGroup(InetAddress multicastAddress) { public ChannelFuture leaveGroup(InetAddress multicastAddress) {
try { try {
return leaveGroup( return leaveGroup(multicastAddress, NetworkInterface.getByInetAddress(getLocalAddress().getAddress()), null);
multicastAddress, NetworkInterface.getByInetAddress(getLocalAddress().getAddress()), null);
} catch (SocketException e) { } catch (SocketException e) {
return Channels.failedFuture(this, e); return Channels.failedFuture(this, e);
} }
@ -225,8 +222,7 @@ public final class NioDatagramChannel extends AbstractNioChannel<DatagramChannel
while (keyIt.hasNext()) { while (keyIt.hasNext()) {
MembershipKey key = keyIt.next(); MembershipKey key = keyIt.next();
if (networkInterface.equals(key.networkInterface())) { if (networkInterface.equals(key.networkInterface())) {
if (source == null && key.sourceAddress() == null || if (source == null && key.sourceAddress() == null || source != null && source.equals(key.sourceAddress())) {
source != null && source.equals(key.sourceAddress())) {
key.drop(); key.drop();
keyIt.remove(); keyIt.remove();
} }

View File

@ -144,8 +144,7 @@ public class NioDatagramChannelFactory implements DatagramChannelFactory {
* Use {@link #NioDatagramChannelFactory(WorkerPool, InternetProtocolFamily)} if unsure. * Use {@link #NioDatagramChannelFactory(WorkerPool, InternetProtocolFamily)} if unsure.
* *
* @param workerPool * @param workerPool
* the {@link WorkerPool} which will be used to obtain the {@link NioDatagramWorker} that execute * the {@link WorkerPool} which will be used to obtain the {@link NioDatagramWorker} that execute the I/O worker threads
* the I/O worker threads
*/ */
public NioDatagramChannelFactory(WorkerPool<NioDatagramWorker> workerPool) { public NioDatagramChannelFactory(WorkerPool<NioDatagramWorker> workerPool) {
this(workerPool, null); this(workerPool, null);
@ -187,8 +186,7 @@ public class NioDatagramChannelFactory implements DatagramChannelFactory {
* Creates a new instance. * Creates a new instance.
* *
* @param workerPool * @param workerPool
* the {@link WorkerPool} which will be used to obtain the {@link Worker} that execute * the {@link WorkerPool} which will be used to obtain the {@link Worker} that execute the I/O worker threads
* the I/O worker threads
* @param family * @param family
* the {@link InternetProtocolFamily} to use. This should be used for UDP multicast. * the {@link InternetProtocolFamily} to use. This should be used for UDP multicast.
* <strong>Be aware that this option is only considered when running on java7+</strong> * <strong>Be aware that this option is only considered when running on java7+</strong>

View File

@ -38,9 +38,8 @@ class NioDatagramPipelineSink extends AbstractNioChannelSink {
private final WorkerPool<NioDatagramWorker> workerPool; private final WorkerPool<NioDatagramWorker> workerPool;
/** /**
* Creates a new {@link NioDatagramPipelineSink} with a the number of {@link NioDatagramWorker}s * Creates a new {@link NioDatagramPipelineSink} with a the number of {@link NioDatagramWorker}s specified in workerCount.
* specified in workerCount. The {@link NioDatagramWorker}s take care of reading and writing * The {@link NioDatagramWorker}s take care of reading and writing for the {@link NioDatagramChannel}.
* for the {@link NioDatagramChannel}.
* *
* @param workerExecutor * @param workerExecutor
* the {@link Executor} that will run the {@link NioDatagramWorker}s * the {@link Executor} that will run the {@link NioDatagramWorker}s

View File

@ -1,37 +1,37 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
* Default implementation which hands of {@link NioDatagramWorker}'s * Default implementation which hands of {@link NioDatagramWorker}'s
* *
* *
*/ */
public class NioDatagramWorkerPool extends AbstractNioWorkerPool<NioDatagramWorker> { public class NioDatagramWorkerPool extends AbstractNioWorkerPool<NioDatagramWorker> {
public NioDatagramWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) { public NioDatagramWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) {
super(executor, workerCount, allowShutdownOnIdle); super(executor, workerCount, allowShutdownOnIdle);
} }
@Override @Override
protected NioDatagramWorker createWorker(Executor executor, boolean allowShutdownOnIdle) { protected NioDatagramWorker createWorker(Executor executor, boolean allowShutdownOnIdle) {
return new NioDatagramWorker(executor, allowShutdownOnIdle); return new NioDatagramWorker(executor, allowShutdownOnIdle);
} }
} }

View File

@ -90,8 +90,7 @@ public class NioServerSocketChannelFactory implements ServerSocketChannelFactory
private final ChannelSink sink; private final ChannelSink sink;
/** /**
* Create a new {@link NioServerSocketChannelFactory} using {@link Executors#newCachedThreadPool()} * Create a new {@link NioServerSocketChannelFactory} using {@link Executors#newCachedThreadPool()} for the boss and worker.
* for the boss and worker.
* *
* See {@link #NioServerSocketChannelFactory(Executor, Executor)} * See {@link #NioServerSocketChannelFactory(Executor, Executor)}
*/ */
@ -137,8 +136,7 @@ public class NioServerSocketChannelFactory implements ServerSocketChannelFactory
* @param bossExecutor * @param bossExecutor
* the {@link Executor} which will execute the boss threads * the {@link Executor} which will execute the boss threads
* @param workerPool * @param workerPool
* the {@link WorkerPool} which will be used to obtain the {@link NioWorker} that execute * the {@link WorkerPool} which will be used to obtain the {@link NioWorker} that execute the I/O worker threads
* the I/O worker threads
*/ */
public NioServerSocketChannelFactory( public NioServerSocketChannelFactory(
Executor bossExecutor, WorkerPool<NioWorker> workerPool) { Executor bossExecutor, WorkerPool<NioWorker> workerPool) {

View File

@ -42,11 +42,9 @@ import org.jboss.netty.channel.socket.SocketChannelConfig;
* </tr><tr> * </tr><tr>
* <td>{@code "writeSpinCount"}</td><td>{@link #setWriteSpinCount(int)}</td> * <td>{@code "writeSpinCount"}</td><td>{@link #setWriteSpinCount(int)}</td>
* </tr><tr> * </tr><tr>
* <td>{@code "receiveBufferSizePredictor"}</td> * <td>{@code "receiveBufferSizePredictor"}</td><td>{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)}</td>
* <td>{@link #setReceiveBufferSizePredictor(ReceiveBufferSizePredictor)}</td>
* </tr><tr> * </tr><tr>
* <td>{@code "receiveBufferSizePredictorFactory"}</td> * <td>{@code "receiveBufferSizePredictorFactory"}</td><td>{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)}</td>
* <td>{@link #setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory)}</td>
* </tr> * </tr>
* </table> * </table>
*/ */

View File

@ -1,37 +1,37 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
/** /**
* Default implementation which hands of {@link NioWorker}'s * Default implementation which hands of {@link NioWorker}'s
* *
* *
*/ */
public class NioWorkerPool extends AbstractNioWorkerPool<NioWorker> { public class NioWorkerPool extends AbstractNioWorkerPool<NioWorker> {
public NioWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) { public NioWorkerPool(Executor executor, int workerCount, boolean allowShutdownOnIdle) {
super(executor, workerCount, allowShutdownOnIdle); super(executor, workerCount, allowShutdownOnIdle);
} }
@Override @Override
protected NioWorker createWorker(Executor executor, boolean allowShutdownOnIdle) { protected NioWorker createWorker(Executor executor, boolean allowShutdownOnIdle) {
return new NioWorker(executor, allowShutdownOnIdle); return new NioWorker(executor, allowShutdownOnIdle);
} }
} }

View File

@ -1,48 +1,47 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import org.jboss.netty.channel.socket.Worker; import org.jboss.netty.channel.socket.Worker;
import org.jboss.netty.util.ExternalResourceReleasable; import org.jboss.netty.util.ExternalResourceReleasable;
/** /**
* This implementation of a {@link WorkerPool} should be used if you plan to share a * 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
* {@link WorkerPool} between different Factories. You will need to call {@link #destroy()} by your * you want to release any resources of it.
* own once you want to release any resources of it. *
* *
* */
*/ public final class ShareableWorkerPool<E extends Worker> implements WorkerPool<E> {
public final class ShareableWorkerPool<E extends Worker> implements WorkerPool<E> {
private final WorkerPool<E> wrapped;
private final WorkerPool<E> wrapped;
public ShareableWorkerPool(WorkerPool<E> wrapped) {
public ShareableWorkerPool(WorkerPool<E> wrapped) { this.wrapped = wrapped;
this.wrapped = wrapped; }
}
public E nextWorker() {
public E nextWorker() { return wrapped.nextWorker();
return wrapped.nextWorker(); }
}
/**
/** * Destroy the {@link ShareableWorkerPool} and release all resources. After this is called its not usable anymore
* Destroy the {@link ShareableWorkerPool} and release all resources. After this is called its not usable anymore */
*/ public void destroy() {
public void destroy() { if (wrapped instanceof ExternalResourceReleasable) {
if (wrapped instanceof ExternalResourceReleasable) { ((ExternalResourceReleasable) wrapped).releaseExternalResources();
((ExternalResourceReleasable) wrapped).releaseExternalResources(); }
} }
} }
}

View File

@ -27,6 +27,7 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.CompositeChannelBuffer; import org.jboss.netty.buffer.CompositeChannelBuffer;
import org.jboss.netty.channel.DefaultFileRegion; import org.jboss.netty.channel.DefaultFileRegion;
import org.jboss.netty.channel.FileRegion; import org.jboss.netty.channel.FileRegion;
import org.jboss.netty.util.internal.DetectionUtil;
final class SocketSendBufferPool { final class SocketSendBufferPool {
@ -367,8 +368,7 @@ final class SocketSendBufferPool {
public void release() { public void release() {
if (file instanceof DefaultFileRegion) { if (file instanceof DefaultFileRegion) {
if (((DefaultFileRegion) file).releaseAfterTransfer()) { if (((DefaultFileRegion) file).releaseAfterTransfer()) {
// Make sure the FileRegion resource are released otherwise it may cause a FD // Make sure the FileRegion resource are released otherwise it may cause a FD leak or something similar
// leak or something similar
file.releaseExternalResources(); file.releaseExternalResources();
} }
} }

View File

@ -1,35 +1,35 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.nio; package org.jboss.netty.channel.socket.nio;
import org.jboss.netty.channel.socket.Worker; import org.jboss.netty.channel.socket.Worker;
/** /**
* The {@link WorkerPool} is responsible to hand of {@link Worker}'s on demand * The {@link WorkerPool} is responsible to hand of {@link Worker}'s on demand
* *
*/ */
public interface WorkerPool<E extends Worker> { public interface WorkerPool<E extends Worker> {
/** /**
* Return the next {@link Worker} to use * Return the next {@link Worker} to use
* *
* @return worker * @return worker
*/ */
E nextWorker(); E nextWorker();
} }

View File

@ -1,117 +1,117 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.oio; package org.jboss.netty.channel.socket.oio;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import org.jboss.netty.channel.AbstractChannel; import org.jboss.netty.channel.AbstractChannel;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelSink; import org.jboss.netty.channel.ChannelSink;
import org.jboss.netty.channel.socket.Worker; import org.jboss.netty.channel.socket.Worker;
abstract class AbstractOioChannel extends AbstractChannel { abstract class AbstractOioChannel extends AbstractChannel {
private volatile InetSocketAddress localAddress; private volatile InetSocketAddress localAddress;
volatile InetSocketAddress remoteAddress; volatile InetSocketAddress remoteAddress;
volatile Thread workerThread; volatile Thread workerThread;
volatile Worker worker; volatile Worker worker;
final Object interestOpsLock = new Object(); final Object interestOpsLock = new Object();
AbstractOioChannel( AbstractOioChannel(
Channel parent, Channel parent,
ChannelFactory factory, ChannelFactory factory,
ChannelPipeline pipeline, ChannelPipeline pipeline,
ChannelSink sink) { ChannelSink sink) {
super(parent, factory, pipeline, sink); super(parent, factory, pipeline, sink);
} }
@Override @Override
protected boolean setClosed() { protected boolean setClosed() {
return super.setClosed(); return super.setClosed();
} }
@Override @Override
protected void setInterestOpsNow(int interestOps) { protected void setInterestOpsNow(int interestOps) {
super.setInterestOpsNow(interestOps); super.setInterestOpsNow(interestOps);
} }
@Override @Override
public ChannelFuture write(Object message, SocketAddress remoteAddress) { public ChannelFuture write(Object message, SocketAddress remoteAddress) {
if (remoteAddress == null || remoteAddress.equals(getRemoteAddress())) { if (remoteAddress == null || remoteAddress.equals(getRemoteAddress())) {
return super.write(message, null); return super.write(message, null);
} else { } else {
return super.write(message, remoteAddress); return super.write(message, remoteAddress);
} }
} }
public boolean isBound() { public boolean isBound() {
return isOpen() && isSocketBound(); return isOpen() && isSocketBound();
} }
public boolean isConnected() { public boolean isConnected() {
return isOpen() && isSocketConnected(); return isOpen() && isSocketConnected();
} }
public InetSocketAddress getLocalAddress() { public InetSocketAddress getLocalAddress() {
InetSocketAddress localAddress = this.localAddress; InetSocketAddress localAddress = this.localAddress;
if (localAddress == null) { if (localAddress == null) {
try { try {
this.localAddress = localAddress = getLocalSocketAddress(); this.localAddress = localAddress = getLocalSocketAddress();
} catch (Throwable t) { } catch (Throwable t) {
// Sometimes fails on a closed socket in Windows. // Sometimes fails on a closed socket in Windows.
return null; return null;
} }
} }
return localAddress; return localAddress;
} }
public InetSocketAddress getRemoteAddress() { public InetSocketAddress getRemoteAddress() {
InetSocketAddress remoteAddress = this.remoteAddress; InetSocketAddress remoteAddress = this.remoteAddress;
if (remoteAddress == null) { if (remoteAddress == null) {
try { try {
this.remoteAddress = remoteAddress = this.remoteAddress = remoteAddress =
getRemoteSocketAddress(); getRemoteSocketAddress();
} catch (Throwable t) { } catch (Throwable t) {
// Sometimes fails on a closed socket in Windows. // Sometimes fails on a closed socket in Windows.
return null; return null;
} }
} }
return remoteAddress; return remoteAddress;
} }
abstract boolean isSocketBound(); abstract boolean isSocketBound();
abstract boolean isSocketConnected(); abstract boolean isSocketConnected();
abstract boolean isSocketClosed(); abstract boolean isSocketClosed();
abstract InetSocketAddress getLocalSocketAddress() throws Exception; abstract InetSocketAddress getLocalSocketAddress() throws Exception;
abstract InetSocketAddress getRemoteSocketAddress() throws Exception; abstract InetSocketAddress getRemoteSocketAddress() throws Exception;
abstract void closeSocket() throws IOException; abstract void closeSocket() throws IOException;
} }

View File

@ -1,57 +1,57 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.oio; package org.jboss.netty.channel.socket.oio;
import org.jboss.netty.channel.AbstractChannelSink; import org.jboss.netty.channel.AbstractChannelSink;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.socket.ChannelRunnableWrapper; import org.jboss.netty.channel.socket.ChannelRunnableWrapper;
import org.jboss.netty.channel.socket.Worker; import org.jboss.netty.channel.socket.Worker;
public abstract class AbstractOioChannelSink extends AbstractChannelSink { public abstract class AbstractOioChannelSink extends AbstractChannelSink {
@Override @Override
public ChannelFuture execute(final ChannelPipeline pipeline, final Runnable task) { public ChannelFuture execute(final ChannelPipeline pipeline, final Runnable task) {
Channel ch = pipeline.getChannel(); Channel ch = pipeline.getChannel();
if (ch instanceof AbstractOioChannel) { if (ch instanceof AbstractOioChannel) {
AbstractOioChannel channel = (AbstractOioChannel) ch; AbstractOioChannel channel = (AbstractOioChannel) ch;
Worker worker = channel.worker; Worker worker = channel.worker;
if (worker != null) { if (worker != null) {
ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task); ChannelRunnableWrapper wrapper = new ChannelRunnableWrapper(pipeline.getChannel(), task);
channel.worker.executeInIoThread(wrapper); channel.worker.executeInIoThread(wrapper);
return wrapper; return wrapper;
} }
} }
return super.execute(pipeline, task); return super.execute(pipeline, task);
} }
@Override @Override
protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) { protected boolean isFireExceptionCaughtLater(ChannelEvent event, Throwable actualCause) {
Channel channel = event.getChannel(); Channel channel = event.getChannel();
boolean fireLater = false; boolean fireLater = false;
if (channel instanceof AbstractOioChannel) { if (channel instanceof AbstractOioChannel) {
fireLater = !AbstractOioWorker.isIoThread((AbstractOioChannel) channel); fireLater = !AbstractOioWorker.isIoThread((AbstractOioChannel) channel);
} }
return fireLater; return fireLater;
} }
} }

View File

@ -1,243 +1,241 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.channel.socket.oio; package org.jboss.netty.channel.socket.oio;
import static org.jboss.netty.channel.Channels.*; import static org.jboss.netty.channel.Channels.*;
import java.io.IOException; import java.io.IOException;
import java.util.Queue; import java.util.Queue;
import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.Channels; import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.Worker; import org.jboss.netty.channel.socket.Worker;
import org.jboss.netty.util.internal.QueueFactory; import org.jboss.netty.util.internal.QueueFactory;
/** /**
* Abstract base class for Oio-Worker implementations * Abstract base class for Oio-Worker implementations
* *
* @param <C> {@link AbstractOioChannel} * @param <C> {@link AbstractOioChannel}
*/ */
abstract class AbstractOioWorker<C extends AbstractOioChannel> implements Worker { abstract class AbstractOioWorker<C extends AbstractOioChannel> implements Worker {
private final Queue<Runnable> eventQueue = QueueFactory.createQueue(Runnable.class); private final Queue<Runnable> eventQueue = QueueFactory.createQueue(Runnable.class);
protected final C channel; protected final C channel;
/** /**
* If this worker has been started thread will be a reference to the thread * 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. * used when starting. i.e. the current thread when the run method is executed.
*/ */
protected volatile Thread thread; protected volatile Thread thread;
private volatile boolean done; private volatile boolean done;
public AbstractOioWorker(C channel) { public AbstractOioWorker(C channel) {
this.channel = channel; this.channel = channel;
channel.worker = this; channel.worker = this;
} }
public void run() { public void run() {
thread = channel.workerThread = Thread.currentThread(); thread = channel.workerThread = Thread.currentThread();
while (channel.isOpen()) { while (channel.isOpen()) {
synchronized (channel.interestOpsLock) { synchronized (channel.interestOpsLock) {
while (!channel.isReadable()) { while (!channel.isReadable()) {
try { try {
// notify() is not called at all. // notify() is not called at all.
// close() and setInterestOps() calls Thread.interrupt() // close() and setInterestOps() calls Thread.interrupt()
channel.interestOpsLock.wait(); channel.interestOpsLock.wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
if (!channel.isOpen()) { if (!channel.isOpen()) {
break; break;
} }
} }
} }
} }
boolean cont = false; boolean cont = false;
try { try {
cont = process(); cont = process();
} catch (Throwable t) { } catch (Throwable t) {
if (!channel.isSocketClosed()) { if (!channel.isSocketClosed()) {
fireExceptionCaught(channel, t); fireExceptionCaught(channel, t);
} }
} finally { } finally {
processEventQueue(); processEventQueue();
if (!cont) { if (!cont) {
break; break;
} }
} }
} }
// Setting the workerThread to null will prevent any channel // Setting the workerThread to null will prevent any channel
// operations from interrupting this thread from now on. // operations from interrupting this thread from now on.
channel.workerThread = null; channel.workerThread = null;
// Clean up. // Clean up.
close(channel, succeededFuture(channel), true); 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 // Mark the worker event loop as done so we know that we need to run tasks directly and not queue them
// See #287 // See #287
done = true; done = true;
// just to make we don't have something left // just to make we don't have something left
processEventQueue(); processEventQueue();
} }
static boolean isIoThread(AbstractOioChannel channel) { static boolean isIoThread(AbstractOioChannel channel) {
return Thread.currentThread() == channel.workerThread; return Thread.currentThread() == channel.workerThread;
} }
public void executeInIoThread(Runnable task) { public void executeInIoThread(Runnable task) {
// check if the current thread is the worker thread // 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. // Also check if the event loop of the worker is complete. If so we need to run the task now.
// See #287 // See #287
if (Thread.currentThread() == thread || done) { if (Thread.currentThread() == thread || done) {
task.run(); task.run();
} else { } else {
boolean added = eventQueue.offer(task); boolean added = eventQueue.offer(task);
if (added) { if (added) {
// as we set the SO_TIMEOUT to 1 second this task will get picked up in 1 second at latest // as we set the SO_TIMEOUT to 1 second this task will get picked up in 1 second at latest
} }
} }
} }
private void processEventQueue() { private void processEventQueue() {
for (;;) { for (;;) {
final Runnable task = eventQueue.poll(); final Runnable task = eventQueue.poll();
if (task == null) { if (task == null) {
break; break;
} }
task.run(); task.run();
} }
} }
/** /**
* Process the incoming messages and also is responsible for call * Process the incoming messages and also is responsible for call {@link Channels#fireMessageReceived(Channel, Object)} once a message
* {@link Channels#fireMessageReceived(Channel, Object)} once a message was processed without * was processed without errors.
* errors. *
* * @return continue returns <code>true</code> as long as this worker should continue to try processing incoming messages
* @return continue returns <code>true</code> as long as this worker should continue to try * @throws IOException
* processing incoming messages */
* @throws IOException abstract boolean process() throws IOException;
*/
abstract boolean process() throws IOException; static void setInterestOps(
AbstractOioChannel channel, ChannelFuture future, int interestOps) {
static void setInterestOps( boolean iothread = isIoThread(channel);
AbstractOioChannel channel, ChannelFuture future, int interestOps) {
boolean iothread = isIoThread(channel); // Override OP_WRITE flag - a user cannot change this flag.
interestOps &= ~Channel.OP_WRITE;
// Override OP_WRITE flag - a user cannot change this flag. interestOps |= channel.getInterestOps() & Channel.OP_WRITE;
interestOps &= ~Channel.OP_WRITE;
interestOps |= channel.getInterestOps() & Channel.OP_WRITE; boolean changed = false;
try {
boolean changed = false; if (channel.getInterestOps() != interestOps) {
try { if ((interestOps & Channel.OP_READ) != 0) {
if (channel.getInterestOps() != interestOps) { channel.setInterestOpsNow(Channel.OP_READ);
if ((interestOps & Channel.OP_READ) != 0) { } else {
channel.setInterestOpsNow(Channel.OP_READ); channel.setInterestOpsNow(Channel.OP_NONE);
} else { }
channel.setInterestOpsNow(Channel.OP_NONE); changed = true;
} }
changed = true;
} future.setSuccess();
if (changed) {
future.setSuccess(); synchronized (channel.interestOpsLock) {
if (changed) { channel.setInterestOpsNow(interestOps);
synchronized (channel.interestOpsLock) {
channel.setInterestOpsNow(interestOps); // Notify the worker so it stops or continues reading.
Thread currentThread = Thread.currentThread();
// Notify the worker so it stops or continues reading. Thread workerThread = channel.workerThread;
Thread currentThread = Thread.currentThread(); if (workerThread != null && currentThread != workerThread) {
Thread workerThread = channel.workerThread; workerThread.interrupt();
if (workerThread != null && currentThread != workerThread) { }
workerThread.interrupt(); }
} if (iothread) {
} fireChannelInterestChanged(channel);
if (iothread) { } else {
fireChannelInterestChanged(channel); fireChannelInterestChangedLater(channel);
} else { }
fireChannelInterestChangedLater(channel); }
} } catch (Throwable t) {
} future.setFailure(t);
} catch (Throwable t) { if (iothread) {
future.setFailure(t); fireExceptionCaught(channel, t);
if (iothread) { } else {
fireExceptionCaught(channel, t); fireExceptionCaughtLater(channel, t);
} else { }
fireExceptionCaughtLater(channel, t); }
} }
}
} static void close(AbstractOioChannel channel, ChannelFuture future) {
close(channel, future, isIoThread(channel));
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();
private static void close(AbstractOioChannel channel, ChannelFuture future, boolean iothread) { boolean bound = channel.isBound();
boolean connected = channel.isConnected();
boolean bound = channel.isBound(); try {
channel.closeSocket();
try { if (channel.setClosed()) {
channel.closeSocket(); future.setSuccess();
if (channel.setClosed()) { if (connected) {
future.setSuccess(); // Notify the worker so it stops reading.
if (connected) { Thread currentThread = Thread.currentThread();
// Notify the worker so it stops reading. Thread workerThread = channel.workerThread;
Thread currentThread = Thread.currentThread(); if (workerThread != null && currentThread != workerThread) {
Thread workerThread = channel.workerThread; workerThread.interrupt();
if (workerThread != null && currentThread != workerThread) { }
workerThread.interrupt(); if (iothread) {
} fireChannelDisconnected(channel);
if (iothread) { } else {
fireChannelDisconnected(channel); fireChannelDisconnectedLater(channel);
} else { }
fireChannelDisconnectedLater(channel); }
} if (bound) {
} if (iothread) {
if (bound) { fireChannelUnbound(channel);
if (iothread) { } else {
fireChannelUnbound(channel); fireChannelUnboundLater(channel);
} else { }
fireChannelUnboundLater(channel); }
} if (iothread) {
} fireChannelClosed(channel);
if (iothread) { } else {
fireChannelClosed(channel); fireChannelClosedLater(channel);
} else { }
fireChannelClosedLater(channel); } else {
} future.setSuccess();
} else { }
future.setSuccess(); } catch (Throwable t) {
} future.setFailure(t);
} catch (Throwable t) { if (iothread) {
future.setFailure(t); fireExceptionCaught(channel, t);
if (iothread) { } else {
fireExceptionCaught(channel, t); fireExceptionCaughtLater(channel, t);
} else { }
fireExceptionCaughtLater(channel, t); }
} }
} }
}
}

View File

@ -91,8 +91,7 @@ public class OioServerSocketChannelFactory implements ServerSocketChannelFactory
private final ChannelSink sink; private final ChannelSink sink;
/** /**
* Create a new {@link OioServerSocketChannelFactory} with a {@link Executors#newCachedThreadPool()} * Create a new {@link OioServerSocketChannelFactory} with a {@link Executors#newCachedThreadPool()} for the boss and worker executor.
* for the boss and worker executor.
* *
* See {@link #OioServerSocketChannelFactory(Executor, Executor)} * See {@link #OioServerSocketChannelFactory(Executor, Executor)}
*/ */

View File

@ -94,8 +94,8 @@ class OioWorker extends AbstractOioWorker<OioSocketChannel> {
try { try {
int length = 0; int length = 0;
// Add support to write a FileRegion. This in fact will not give any performance gain // Add support to write a FileRegion. This in fact will not give any performance gain but at least it not fail and
// but at least it not fail and we did the best to emulate it // we did the best to emulate it
if (message instanceof FileRegion) { if (message instanceof FileRegion) {
FileRegion fr = (FileRegion) message; FileRegion fr = (FileRegion) message;
try { try {

View File

@ -138,8 +138,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelUpstreamHandler {
SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince); Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);
// Only compare up to the second because the datetime format we send to the client does // Only compare up to the second because the datetime format we send to the client does not have milliseconds
// not have milliseconds
long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000; long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
long fileLastModifiedSeconds = file.lastModified() / 1000; long fileLastModifiedSeconds = file.lastModified() / 1000;
if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
@ -298,8 +297,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelUpstreamHandler {
time.add(Calendar.SECOND, HTTP_CACHE_SECONDS); time.add(Calendar.SECOND, HTTP_CACHE_SECONDS);
response.setHeader(HttpHeaders.Names.EXPIRES, dateFormatter.format(time.getTime())); 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.CACHE_CONTROL, "private, max-age=" + HTTP_CACHE_SECONDS);
response.setHeader( response.setHeader(HttpHeaders.Names.LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified())));
HttpHeaders.Names.LAST_MODIFIED, dateFormatter.format(new Date(fileToCache.lastModified())));
} }
/** /**

View File

@ -132,8 +132,7 @@ public class HttpSnoopServerHandler extends SimpleChannelUpstreamHandler {
if (keepAlive) { if (keepAlive) {
// Add 'Content-Length' header only for a keep-alive connection. // Add 'Content-Length' header only for a keep-alive connection.
response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes()); response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
// Add keep alive header as per: // Add keep alive header as per http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection
// - http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Connection
response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); response.setHeader(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
} }

View File

@ -430,8 +430,7 @@ public class HttpUploadServerHandler extends SimpleChannelUpstreamHandler {
responseContent responseContent
.append("<tr><td>Fill with value: <br> <textarea name=\"thirdinfo\" cols=40 rows=10></textarea>"); .append("<tr><td>Fill with value: <br> <textarea name=\"thirdinfo\" cols=40 rows=10></textarea>");
responseContent responseContent
.append("<tr><td>Fill with file (only file name will be transmitted): <br> " + .append("<tr><td>Fill with file (only file name will be transmitted): <br> <input type=file name=\"myfile\">");
"<input type=file name=\"myfile\">");
responseContent.append("</td></tr>"); responseContent.append("</td></tr>");
responseContent responseContent
.append("<tr><td><INPUT TYPE=\"submit\" NAME=\"Send\" VALUE=\"Send\"></INPUT></td>"); .append("<tr><td><INPUT TYPE=\"submit\" NAME=\"Send\" VALUE=\"Send\"></INPUT></td>");

View File

@ -27,50 +27,67 @@ public final class WebSocketServerIndexPage {
private static final String NEWLINE = "\r\n"; private static final String NEWLINE = "\r\n";
public static ChannelBuffer getContent(String webSocketLocation) { public static ChannelBuffer getContent(String webSocketLocation) {
return ChannelBuffers.copiedBuffer( return ChannelBuffers
"<html><head><title>Web Socket Test</title></head>" + NEWLINE + .copiedBuffer(
"<body>" + NEWLINE + "<html><head><title>Web Socket Test</title></head>"
"<script type=\"text/javascript\">" + NEWLINE + + NEWLINE
"var socket;" + NEWLINE + + "<body>"
"if (!window.WebSocket) {" + NEWLINE + + NEWLINE
" window.WebSocket = window.MozWebSocket;" + NEWLINE + + "<script type=\"text/javascript\">"
"}" + NEWLINE + + NEWLINE
"if (window.WebSocket) {" + NEWLINE + + "var socket;"
" socket = new WebSocket(\"" + webSocketLocation + "\");" + NEWLINE + + NEWLINE
" socket.onmessage = function(event) {" + NEWLINE + + "if (!window.WebSocket) {"
" var ta = document.getElementById('responseText');" + NEWLINE + + NEWLINE
" ta.value = ta.value + '\\n' + event.data" + NEWLINE + + " window.WebSocket = window.MozWebSocket;"
" };" + NEWLINE + + NEWLINE
" socket.onopen = function(event) {" + NEWLINE + + "}"
" var ta = document.getElementById('responseText');" + NEWLINE + + NEWLINE
" ta.value = \"Web Socket opened!\";" + NEWLINE + + "if (window.WebSocket) {"
" };" + NEWLINE + + NEWLINE
" socket.onclose = function(event) {" + NEWLINE + + " socket = new WebSocket(\""
" var ta = document.getElementById('responseText');" + NEWLINE + + webSocketLocation
" ta.value = ta.value + \"Web Socket closed\"; " + NEWLINE + + "\");"
" };" + NEWLINE + + NEWLINE
"} else {" + NEWLINE + + " socket.onmessage = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + '\\n' + event.data };"
" alert(\"Your browser does not support Web Socket.\");" + NEWLINE + + NEWLINE
"}" + NEWLINE + + " socket.onopen = function(event) { var ta = document.getElementById('responseText'); ta.value = \"Web Socket opened!\"; };"
NEWLINE + + NEWLINE
"function send(message) {" + NEWLINE + + " socket.onclose = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + \"Web Socket closed\"; };"
" if (!window.WebSocket) { return; }" + NEWLINE + + NEWLINE
" if (socket.readyState == WebSocket.OPEN) {" + NEWLINE + + "} else {"
" socket.send(message);" + NEWLINE + + NEWLINE
" } else {" + NEWLINE + + " alert(\"Your browser does not support Web Socket.\");"
" alert(\"The socket is not open.\");" + NEWLINE + + NEWLINE
" }" + NEWLINE + + "}"
"}" + NEWLINE + + NEWLINE
"</script>" + NEWLINE + + NEWLINE
"<form onsubmit=\"return false;\">" + NEWLINE + + "function send(message) {"
"<input type=\"text\" name=\"message\" value=\"Hello, World!\"/>" + + NEWLINE
"<input type=\"button\" value=\"Send Web Socket Data\"" + NEWLINE + + " if (!window.WebSocket) { return; }"
" onclick=\"send(this.form.message.value)\" />" + NEWLINE + + NEWLINE
"<h3>Output</h3>" + NEWLINE + + " if (socket.readyState == WebSocket.OPEN) {"
"<textarea id=\"responseText\" style=\"width:500px;height:300px;\"></textarea>" + NEWLINE + + NEWLINE
"</form>" + NEWLINE + + " socket.send(message);"
"</body>" + NEWLINE + + NEWLINE
"</html>" + NEWLINE, CharsetUtil.US_ASCII); + " } else {"
+ NEWLINE
+ " alert(\"The socket is not open.\");"
+ NEWLINE
+ " }"
+ NEWLINE
+ "}"
+ NEWLINE
+ "</script>"
+ NEWLINE
+ "<form onsubmit=\"return false;\">"
+ NEWLINE
+ "<input type=\"text\" name=\"message\" value=\"Hello, World!\"/>"
+ "<input type=\"button\" value=\"Send Web Socket Data\" onclick=\"send(this.form.message.value)\" />"
+ NEWLINE + "<h3>Output</h3>" + NEWLINE
+ "<textarea id=\"responseText\" style=\"width: 500px; height:300px;\"></textarea>"
+ NEWLINE + "</form>" + NEWLINE + "</body>" + NEWLINE + "</html>" + NEWLINE,
CharsetUtil.US_ASCII);
} }
private WebSocketServerIndexPage() { private WebSocketServerIndexPage() {

View File

@ -29,7 +29,6 @@ import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler; 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.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest; import org.jboss.netty.handler.codec.http.HttpRequest;
@ -76,7 +75,7 @@ public class WebSocketSslServerHandler extends SimpleChannelUpstreamHandler {
if (req.getUri().equals("/")) { if (req.getUri().equals("/")) {
HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK); HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);
ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); ChannelBuffer content = WebSocketSslServerIndexPage.getContent(getWebSocketLocation(req));
res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8"); res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");
setContentLength(res, content.readableBytes()); setContentLength(res, content.readableBytes());

View File

@ -0,0 +1,96 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package org.jboss.netty.example.http.websocketx.sslserver;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.util.CharsetUtil;
/**
* Generates the demo HTML page which is served at http://localhost:8080/
*/
public final class WebSocketSslServerIndexPage {
private static final String NEWLINE = "\r\n";
public static ChannelBuffer getContent(String webSocketLocation) {
return ChannelBuffers
.copiedBuffer(
"<html><head><title>Web Socket Test</title></head>"
+ NEWLINE
+ "<body>"
+ NEWLINE
+ "<script type=\"text/javascript\">"
+ NEWLINE
+ "var socket;"
+ NEWLINE
+ "if (!window.WebSocket) {"
+ NEWLINE
+ " window.WebSocket = window.MozWebSocket;"
+ NEWLINE
+ "}"
+ NEWLINE
+ "if (window.WebSocket) {"
+ NEWLINE
+ " socket = new WebSocket(\""
+ webSocketLocation
+ "\");"
+ NEWLINE
+ " socket.onmessage = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + '\\n' + event.data };"
+ NEWLINE
+ " socket.onopen = function(event) { var ta = document.getElementById('responseText'); ta.value = \"Web Socket opened!\"; };"
+ NEWLINE
+ " socket.onclose = function(event) { var ta = document.getElementById('responseText'); ta.value = ta.value + \"Web Socket closed\"; };"
+ NEWLINE
+ "} else {"
+ NEWLINE
+ " alert(\"Your browser does not support Web Socket.\");"
+ NEWLINE
+ "}"
+ NEWLINE
+ NEWLINE
+ "function send(message) {"
+ NEWLINE
+ " if (!window.WebSocket) { return; }"
+ NEWLINE
+ " if (socket.readyState == WebSocket.OPEN) {"
+ NEWLINE
+ " socket.send(message);"
+ NEWLINE
+ " } else {"
+ NEWLINE
+ " alert(\"The socket is not open.\");"
+ NEWLINE
+ " }"
+ NEWLINE
+ "}"
+ NEWLINE
+ "</script>"
+ NEWLINE
+ "<form onsubmit=\"return false;\">"
+ NEWLINE
+ "<input type=\"text\" name=\"message\" value=\"Hello, World!\"/>"
+ "<input type=\"button\" value=\"Send Web Socket Data\" onclick=\"send(this.form.message.value)\" />"
+ NEWLINE + "<h3>Output</h3>" + NEWLINE
+ "<textarea id=\"responseText\" style=\"width: 500px; height:300px;\"></textarea>"
+ NEWLINE + "</form>" + NEWLINE + "</body>" + NEWLINE + "</html>" + NEWLINE,
CharsetUtil.US_ASCII);
}
private WebSocketSslServerIndexPage() {
// Unused
}
}

View File

@ -34,7 +34,7 @@ import org.jboss.netty.util.CharsetUtil;
* A UDP broadcast client that asks for a quote of the moment (QOTM) to * A UDP broadcast client that asks for a quote of the moment (QOTM) to
* {@link QuoteOfTheMomentServer}. * {@link QuoteOfTheMomentServer}.
* *
* Inspired by <a href="http://goo.gl/BsXVR">the official Java tutorial</a>. * Inspired by <a href="http://java.sun.com/docs/books/tutorial/networking/datagrams/clientServer.html">the official Java tutorial</a>.
*/ */
public class QuoteOfTheMomentClient { public class QuoteOfTheMomentClient {

View File

@ -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 * A UDP server that responds to the QOTM (quote of the moment) request to a
* {@link QuoteOfTheMomentClient}. * {@link QuoteOfTheMomentClient}.
* *
* Inspired by <a href="http://goo.gl/BsXVR">the official Java tutorial</a>. * Inspired by <a href="http://java.sun.com/docs/books/tutorial/networking/datagrams/clientServer.html">the official Java tutorial</a>.
*/ */
public class QuoteOfTheMomentServer { public class QuoteOfTheMomentServer {

View File

@ -16,7 +16,6 @@
package org.jboss.netty.example.securechat; package org.jboss.netty.example.securechat;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security; import java.security.Security;
import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManager;
@ -43,10 +42,10 @@ import org.jboss.netty.handler.ssl.SslHandler;
* {@link SslHandler}.</li> * {@link SslHandler}.</li>
* <li>When initializing an {@link SSLContext} on the client side, * <li>When initializing an {@link SSLContext} on the client side,
* specify the {@link KeyManager} that contains the client certificate as * specify the {@link KeyManager} that contains the client certificate as
* the first argument of {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}.</li> * the first argument of {@link SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)}.</li>
* <li>When initializing an {@link SSLContext} on the server side, * <li>When initializing an {@link SSLContext} on the server side,
* specify the proper {@link TrustManager} as the second argument of * specify the proper {@link TrustManager} as the second argument of
* {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)} * {@link SSLContext#init(KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom)}
* to validate the client certificate.</li> * to validate the client certificate.</li>
* </ul> * </ul>
*/ */

View File

@ -28,9 +28,7 @@ import org.jboss.netty.buffer.HeapChannelBufferFactory;
* <a href="http://en.wikipedia.org/wiki/Base64">Base64</a> notation. * <a href="http://en.wikipedia.org/wiki/Base64">Base64</a> notation.
* <p> * <p>
* The encoding and decoding algorithm in this class has been derived from * The encoding and decoding algorithm in this class has been derived from
* <a href="http://iharder.sourceforge.net/current/java/base64/">Robert Harder's Public Domain * <a href="http://iharder.sourceforge.net/current/java/base64/">Robert Harder's Public Domain Base64 Encoder/Decoder</a>.
* Base64 Encoder/Decoder</a>.
*
* @apiviz.landmark * @apiviz.landmark
* @apiviz.uses org.jboss.netty.handler.codec.base64.Base64Dialect * @apiviz.uses org.jboss.netty.handler.codec.base64.Base64Dialect
*/ */
@ -127,8 +125,7 @@ public final class Base64 {
return encode(src, off, len, Base64Dialect.STANDARD, bufferFactory); return encode(src, off, len, Base64Dialect.STANDARD, bufferFactory);
} }
public static ChannelBuffer encode( public static ChannelBuffer encode(ChannelBuffer src, int off, int len, Base64Dialect dialect, ChannelBufferFactory bufferFactory) {
ChannelBuffer src, int off, int len, Base64Dialect dialect, ChannelBufferFactory bufferFactory) {
return encode(src, off, len, breakLines(dialect), dialect, bufferFactory); return encode(src, off, len, breakLines(dialect), dialect, bufferFactory);
} }

View File

@ -23,8 +23,7 @@ package org.jboss.netty.handler.codec.base64;
* Enumeration of supported Base64 dialects. * Enumeration of supported Base64 dialects.
* <p> * <p>
* The internal lookup tables in this class has been derived from * The internal lookup tables in this class has been derived from
* <a href="http://iharder.sourceforge.net/current/java/base64/">Robert Harder's Public Domain * <a href="http://iharder.sourceforge.net/current/java/base64/">Robert Harder's Public Domain Base64 Encoder/Decoder</a>.
* Base64 Encoder/Decoder</a>.
*/ */
public enum Base64Dialect { public enum Base64Dialect {
/** /**

View File

@ -25,8 +25,7 @@ import org.jboss.netty.channel.DefaultChannelConfig;
/** /**
* TODO Make EmbeddedChannel implement ChannelConfig and ChannelSink to reduce overhead. * TODO Make EmbeddedChannel implement ChannelConfig and ChannelSink to reduce overhead.
* TODO Do not extend AbstractChannel to reduce overhead and remove the internal-use-only * TODO Do not extend AbstractChannel to reduce overhead and remove the internal-use-only constructor in AbstractChannel.
* constructor in AbstractChannel.
*/ */
class EmbeddedChannel extends AbstractChannel { class EmbeddedChannel extends AbstractChannel {

View File

@ -34,7 +34,7 @@ import org.jboss.netty.util.CharsetUtil;
* <pre> * <pre>
* String data = "foobar"; * String data = "foobar";
* *
* {@link EncoderEmbedder}&lt;{@link ChannelBuffer}&gt; embedder = new {@link EncoderEmbedder}&lt;&gt;( * {@link EncoderEmbedder}&lt;{@link ChannelBuffer}&gt; embedder = new {@link EncoderEmbedder}&lt;{@link ChannelBuffer}&gt;(
* new {@link Base64Encoder}(), new {@link StringEncoder}()); * new {@link Base64Encoder}(), new {@link StringEncoder}());
* *
* embedder.offer(data); * embedder.offer(data);

View File

@ -51,11 +51,8 @@ public class FixedLengthFrameDecoder extends FrameDecoder {
/** /**
* Creates a new instance. * Creates a new instance.
* *
* @param frameLength * @param frameLength the length of the frame
* the length of the frame * @param allocateFullBuffer <code>true</code> if the cumulative {@link ChannelBuffer} should use the {@link #frameLength} as its initial size
* @param allocateFullBuffer
* <code>true</code> if the cumulative {@link ChannelBuffer} should use the
* {@link #frameLength} as its initial size
*/ */
public FixedLengthFrameDecoder(int frameLength, boolean allocateFullBuffer) { public FixedLengthFrameDecoder(int frameLength, boolean allocateFullBuffer) {
if (frameLength <= 0) { if (frameLength <= 0) {

View File

@ -214,8 +214,7 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
callDecode(ctx, e.getChannel(), input, e.getRemoteAddress()); callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
} finally { } finally {
if (input.readable()) { if (input.readable()) {
// seems like there is something readable left in the input buffer. So create // seems like there is something readable left in the input buffer. So create the cumulation buffer and copy the input into it
// the cumulation buffer and copy the input into it
(cumulation = newCumulationBuffer(ctx, input.readableBytes())).writeBytes(input); (cumulation = newCumulationBuffer(ctx, input.readableBytes())).writeBytes(input);
} }
} }
@ -351,8 +350,7 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
} }
} }
protected final void unfoldAndFireMessageReceived( protected final void unfoldAndFireMessageReceived(ChannelHandlerContext context, SocketAddress remoteAddress, Object result) {
ChannelHandlerContext context, SocketAddress remoteAddress, Object result) {
if (unfold) { if (unfold) {
if (result instanceof Object[]) { if (result instanceof Object[]) {
for (Object r: (Object[]) result) { for (Object r: (Object[]) result) {
@ -371,8 +369,8 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
} }
/** /**
* Gets called on {@link #channelDisconnected(ChannelHandlerContext, ChannelStateEvent)} and * Gets called on {@link #channelDisconnected(ChannelHandlerContext, ChannelStateEvent)} and {@link #channelClosed(ChannelHandlerContext, ChannelStateEvent)}
* {@link #channelClosed(ChannelHandlerContext, ChannelStateEvent)} *
*/ */
protected void cleanup(ChannelHandlerContext ctx, ChannelStateEvent e) protected void cleanup(ChannelHandlerContext ctx, ChannelStateEvent e)
throws Exception { throws Exception {
@ -422,8 +420,7 @@ public abstract class FrameDecoder extends SimpleChannelUpstreamHandler implemen
*/ */
public void replace(String handlerName, ChannelHandler handler) { public void replace(String handlerName, ChannelHandler handler) {
if (ctx == null) { if (ctx == null) {
throw new IllegalStateException( throw new IllegalStateException("Replace cann only be called once the FrameDecoder is added to the ChannelPipeline");
"Replace cann only be called once the FrameDecoder is added to the ChannelPipeline");
} }
ChannelPipeline pipeline = ctx.getPipeline(); ChannelPipeline pipeline = ctx.getPipeline();
pipeline.addAfter(ctx.getName(), handlerName, handler); pipeline.addAfter(ctx.getName(), handlerName, handler);

View File

@ -41,8 +41,8 @@ import java.util.regex.Pattern;
*/ */
public class CookieDecoder { public class CookieDecoder {
private static final Pattern PATTERN = Pattern.compile( private static final Pattern PATTERN =
"(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))"); Pattern.compile("(?:\\s|[;,])*\\$*([^;=]+)(?:=(?:[\"']((?:\\\\.|[^\"])*)[\"']|([^;,]*)))?(\\s*(?:[;,]+\\s*|$))");
private static final String COMMA = ","; private static final String COMMA = ",";

View File

@ -219,8 +219,7 @@ public class HttpClientCodec implements ChannelUpstreamHandler,
if (failOnMissingResponse) { if (failOnMissingResponse) {
long missingResponses = requestResponseCounter.get(); long missingResponses = requestResponseCounter.get();
if (missingResponses > 0) { if (missingResponses > 0) {
throw new PrematureChannelClosureException( throw new PrematureChannelClosureException("Channel closed but still missing " + missingResponses + " response(s)");
"Channel closed but still missing " + missingResponses + " response(s)");
} }
} }
} }

View File

@ -150,8 +150,7 @@ public abstract class HttpContentEncoder extends SimpleChannelHandler {
// the last product on closure, // the last product on closure,
if (lastProduct.readable()) { if (lastProduct.readable()) {
Channels.write( Channels.write(
ctx, Channels.succeededFuture(e.getChannel()), ctx, Channels.succeededFuture(e.getChannel()), new DefaultHttpChunk(lastProduct), e.getRemoteAddress());
new DefaultHttpChunk(lastProduct), e.getRemoteAddress());
} }
// Emit the last chunk. // Emit the last chunk.

View File

@ -167,8 +167,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
} }
@Override @Override
protected Object decode( protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception {
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception {
switch (state) { switch (state) {
case SKIP_CONTROL_CHARS: { case SKIP_CONTROL_CHARS: {
try { try {
@ -271,7 +270,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
return readFixedLengthContent(buffer); return readFixedLengthContent(buffer);
} }
case READ_FIXED_LENGTH_CONTENT_AS_CHUNKS: { case READ_FIXED_LENGTH_CONTENT_AS_CHUNKS: {
assert chunkSize <= Integer.MAX_VALUE; assert this.chunkSize <= Integer.MAX_VALUE;
int chunkSize = (int) this.chunkSize; int chunkSize = (int) this.chunkSize;
int readLimit = actualReadableBytes(); int readLimit = actualReadableBytes();
int toRead = chunkSize; int toRead = chunkSize;
@ -324,7 +323,7 @@ public abstract class HttpMessageDecoder extends ReplayingDecoder<HttpMessageDec
return chunk; return chunk;
} }
case READ_CHUNKED_CONTENT_AS_CHUNKS: { case READ_CHUNKED_CONTENT_AS_CHUNKS: {
assert chunkSize <= Integer.MAX_VALUE; assert this.chunkSize <= Integer.MAX_VALUE;
int chunkSize = (int) this.chunkSize; int chunkSize = (int) this.chunkSize;
int readLimit = actualReadableBytes(); int readLimit = actualReadableBytes();
int toRead = chunkSize; int toRead = chunkSize;

View File

@ -26,32 +26,28 @@ import java.util.Map;
*/ */
public class HttpMethod implements Comparable<HttpMethod> { public class HttpMethod implements Comparable<HttpMethod> {
/** /**
* The OPTIONS method represents a request for information about the communication options * The OPTIONS method represents a request for information about the communication options available on the request/response
* available on the request/response chain identified by the Request-URI. This method allows * chain identified by the Request-URI. This method allows the client to determine the options and/or requirements
* the client to determine the options and/or requirements associated with a resource, or the * associated with a resource, or the capabilities of a server, without implying a resource action or initiating a
* capabilities of a server, without implying a resource action or initiating a resource * resource retrieval.
* retrieval.
*/ */
public static final HttpMethod OPTIONS = new HttpMethod("OPTIONS"); public static final HttpMethod OPTIONS = new HttpMethod("OPTIONS");
/** /**
* The GET method means retrieve whatever information (in the form of an entity) is identified * The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI.
* by the Request-URI. If the Request-URI refers to a data-producing process, it is the * If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity
* produced data which shall be returned as the entity in the response and not the source text * in the response and not the source text of the process, unless that text happens to be the output of the process.
* of the process, unless that text happens to be the output of the process.
*/ */
public static final HttpMethod GET = new HttpMethod("GET"); 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 HEAD method is identical to GET except that the server MUST NOT return a message-body in the response.
* the response.
*/ */
public static final HttpMethod HEAD = new HttpMethod("HEAD"); 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 * The POST method is used to request that the origin server accept the entity enclosed in the request as a new
* request as a new subordinate of the resource identified by the Request-URI in the * subordinate of the resource identified by the Request-URI in the Request-Line.
* Request-Line.
*/ */
public static final HttpMethod POST = new HttpMethod("POST"); public static final HttpMethod POST = new HttpMethod("POST");
@ -67,20 +63,17 @@ public class HttpMethod implements Comparable<HttpMethod> {
public static final HttpMethod PATCH = new HttpMethod("PATCH"); public static final HttpMethod PATCH = new HttpMethod("PATCH");
/** /**
* The DELETE method requests that the origin server delete the resource identified by the * The DELETE method requests that the origin server delete the resource identified by the Request-URI.
* Request-URI.
*/ */
public static final HttpMethod DELETE = new HttpMethod("DELETE"); public static final HttpMethod DELETE = new HttpMethod("DELETE");
/** /**
* The TRACE method is used to invoke a remote, application-layer loop- back of the request * The TRACE method is used to invoke a remote, application-layer loop- back of the request message.
* message.
*/ */
public static final HttpMethod TRACE = new HttpMethod("TRACE"); public static final HttpMethod TRACE = new HttpMethod("TRACE");
/** /**
* This specification reserves the method name CONNECT for use with a proxy that can * This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel
* dynamically switch to being a tunnel
*/ */
public static final HttpMethod CONNECT = new HttpMethod("CONNECT"); public static final HttpMethod CONNECT = new HttpMethod("CONNECT");

View File

@ -102,9 +102,7 @@ public class HttpResponseDecoder extends HttpMessageDecoder {
@Override @Override
protected HttpMessage createMessage(String[] initialLine) { protected HttpMessage createMessage(String[] initialLine) {
return new DefaultHttpResponse( return new DefaultHttpResponse(HttpVersion.valueOf(initialLine[0]), new HttpResponseStatus(Integer.valueOf(initialLine[1]), initialLine[2]));
HttpVersion.valueOf(initialLine[0]),
new HttpResponseStatus(Integer.valueOf(initialLine[1]), initialLine[2]));
} }
@Override @Override

View File

@ -56,8 +56,7 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/** /**
* 203 Non-Authoritative Information (since HTTP/1.1) * 203 Non-Authoritative Information (since HTTP/1.1)
*/ */
public static final HttpResponseStatus NON_AUTHORITATIVE_INFORMATION = public static final HttpResponseStatus NON_AUTHORITATIVE_INFORMATION = new HttpResponseStatus(203, "Non-Authoritative Information");
new HttpResponseStatus(203, "Non-Authoritative Information");
/** /**
* 204 No Content * 204 No Content
@ -152,8 +151,7 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/** /**
* 407 Proxy Authentication Required * 407 Proxy Authentication Required
*/ */
public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = new HttpResponseStatus(407, "Proxy Authentication Required");
new HttpResponseStatus(407, "Proxy Authentication Required");
/** /**
* 408 Request Timeout * 408 Request Timeout
@ -183,8 +181,7 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/** /**
* 413 Request Entity Too Large * 413 Request Entity Too Large
*/ */
public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = public static final HttpResponseStatus REQUEST_ENTITY_TOO_LARGE = new HttpResponseStatus(413, "Request Entity Too Large");
new HttpResponseStatus(413, "Request Entity Too Large");
/** /**
* 414 Request-URI Too Long * 414 Request-URI Too Long
@ -194,14 +191,12 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/** /**
* 415 Unsupported Media Type * 415 Unsupported Media Type
*/ */
public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = public static final HttpResponseStatus UNSUPPORTED_MEDIA_TYPE = new HttpResponseStatus(415, "Unsupported Media Type");
new HttpResponseStatus(415, "Unsupported Media Type");
/** /**
* 416 Requested Range Not Satisfiable * 416 Requested Range Not Satisfiable
*/ */
public static final HttpResponseStatus REQUESTED_RANGE_NOT_SATISFIABLE = public static final HttpResponseStatus REQUESTED_RANGE_NOT_SATISFIABLE = new HttpResponseStatus(416, "Requested Range Not Satisfiable");
new HttpResponseStatus(416, "Requested Range Not Satisfiable");
/** /**
* 417 Expectation Failed * 417 Expectation Failed
@ -236,8 +231,7 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/** /**
* 500 Internal Server Error * 500 Internal Server Error
*/ */
public static final HttpResponseStatus INTERNAL_SERVER_ERROR = public static final HttpResponseStatus INTERNAL_SERVER_ERROR = new HttpResponseStatus(500, "Internal Server Error");
new HttpResponseStatus(500, "Internal Server Error");
/** /**
* 501 Not Implemented * 501 Not Implemented
@ -262,14 +256,12 @@ public class HttpResponseStatus implements Comparable<HttpResponseStatus> {
/** /**
* 505 HTTP Version Not Supported * 505 HTTP Version Not Supported
*/ */
public static final HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED = public static final HttpResponseStatus HTTP_VERSION_NOT_SUPPORTED = new HttpResponseStatus(505, "HTTP Version Not Supported");
new HttpResponseStatus(505, "HTTP Version Not Supported");
/** /**
* 506 Variant Also Negotiates (RFC2295) * 506 Variant Also Negotiates (RFC2295)
*/ */
public static final HttpResponseStatus VARIANT_ALSO_NEGOTIATES = public static final HttpResponseStatus VARIANT_ALSO_NEGOTIATES = new HttpResponseStatus(506, "Variant Also Negotiates");
new HttpResponseStatus(506, "Variant Also Negotiates");
/** /**
* 507 Insufficient Storage (WebDAV, RFC4918) * 507 Insufficient Storage (WebDAV, RFC4918)

View File

@ -47,10 +47,10 @@ import org.jboss.netty.util.CharsetUtil;
* *
* <h3>HashDOS vulnerability fix</h3> * <h3>HashDOS vulnerability fix</h3>
* *
* As a workaround to the <a href="http://goo.gl/I4Nky">HashDOS</a> vulnerability, the decoder * As a workaround to the <a href="http://events.ccc.de/congress/2011/Fahrplan/attachments/2007_28C3_Effective_DoS_on_web_application_platforms.pdf">HashDOS</a>
* limits the maximum number of decoded key-value parameter pairs, up to {@literal 1024} by * vulnerability, the decoder limits the maximum number of decoded key-value
* default, and you can configure it when you construct the decoder by passing an additional * parameter pairs, up to {@literal 1024} by default, and you can configure it
* integer parameter. * when you construct the decoder by passing an additional integer parameter.
* *
* @see QueryStringEncoder * @see QueryStringEncoder
* *

View File

@ -461,8 +461,7 @@ public class HttpPostRequestDecoder {
} else if (read == '&') { // special empty FIELD } else if (read == '&') { // special empty FIELD
currentStatus = MultiPartStatus.DISPOSITION; currentStatus = MultiPartStatus.DISPOSITION;
ampersandpos = currentpos - 1; ampersandpos = currentpos - 1;
String key = decodeAttribute( String key = decodeAttribute(undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset);
undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset);
currentAttribute = factory.createAttribute(request, key); currentAttribute = factory.createAttribute(request, key);
currentAttribute.setValue(""); // empty currentAttribute.setValue(""); // empty
addHttpData(currentAttribute); addHttpData(currentAttribute);
@ -588,8 +587,7 @@ public class HttpPostRequestDecoder {
} else if (read == '&') { // special empty FIELD } else if (read == '&') { // special empty FIELD
currentStatus = MultiPartStatus.DISPOSITION; currentStatus = MultiPartStatus.DISPOSITION;
ampersandpos = currentpos - 1; ampersandpos = currentpos - 1;
String key = decodeAttribute( String key = decodeAttribute(undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset);
undecodedChunk.toString(firstpos, ampersandpos - firstpos, charset), charset);
currentAttribute = factory.createAttribute(request, key); currentAttribute = factory.createAttribute(request, key);
currentAttribute.setValue(""); // empty currentAttribute.setValue(""); // empty
addHttpData(currentAttribute); addHttpData(currentAttribute);

View File

@ -20,8 +20,8 @@ import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.util.CharsetUtil; import org.jboss.netty.util.CharsetUtil;
/** /**
* Web Socket continuation frame containing continuation text or binary data. This is used for * Web Socket continuation frame containing continuation text or binary data. This is used for fragmented messages where
* fragmented messages where the contents of a messages is contained more than 1 frame. * the contents of a messages is contained more than 1 frame.
*/ */
public class ContinuationWebSocketFrame extends WebSocketFrame { public class ContinuationWebSocketFrame extends WebSocketFrame {
@ -35,8 +35,7 @@ public class ContinuationWebSocketFrame extends WebSocketFrame {
} }
/** /**
* Creates a new continuation frame with the specified binary data. The final fragment flag is * Creates a new continuation frame with the specified binary data. The final fragment flag is set to true.
* set to true.
* *
* @param binaryData * @param binaryData
* the content of the frame. * the content of the frame.
@ -73,8 +72,7 @@ public class ContinuationWebSocketFrame extends WebSocketFrame {
* @param aggregatedText * @param aggregatedText
* Aggregated text set by decoder on the final continuation frame of a fragmented text message * Aggregated text set by decoder on the final continuation frame of a fragmented text message
*/ */
public ContinuationWebSocketFrame( public ContinuationWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData, String aggregatedText) {
boolean finalFragment, int rsv, ChannelBuffer binaryData, String aggregatedText) {
setFinalFragment(finalFragment); setFinalFragment(finalFragment);
setRsv(rsv); setRsv(rsv);
setBinaryData(binaryData); setBinaryData(binaryData);

View File

@ -18,20 +18,19 @@
* *
* Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* and associated documentation files (the "Software"), to deal in the Software without restriction, * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* including without limitation the rights to use, copy, modify, merge, publish, distribute, * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* substantial portions of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
package org.jboss.netty.handler.codec.http.websocketx; package org.jboss.netty.handler.codec.http.websocketx;

View File

@ -18,20 +18,19 @@
* *
* Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* and associated documentation files (the "Software"), to deal in the Software without restriction, * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
* including without limitation the rights to use, copy, modify, merge, publish, distribute, * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* substantial portions of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
package org.jboss.netty.handler.codec.http.websocketx; package org.jboss.netty.handler.codec.http.websocketx;
@ -42,23 +41,20 @@ final class UTF8Output {
private static final int UTF8_ACCEPT = 0; private static final int UTF8_ACCEPT = 0;
private static final int UTF8_REJECT = 12; 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
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, 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,
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, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
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, 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,
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, 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
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, 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, 12, 12, 12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 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, 24, 12, 12, 12, 12, 12, 24, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 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, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 36, 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, 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, 12, 12 };
12, 12, 12, 12, 12, 12 };
private int state = UTF8_ACCEPT; private int state = UTF8_ACCEPT;
private int codep; private int codep;

View File

@ -27,8 +27,8 @@ public class WebSocketClientHandshakerFactory {
* Instances a new handshaker * Instances a new handshaker
* *
* @param webSocketURL * @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* Subsequent web socket frames will be sent to this URL. * sent to this URL.
* @param version * @param version
* Version of web socket specification to use to connect to the server * Version of web socket specification to use to connect to the server
* @param subprotocol * @param subprotocol
@ -48,8 +48,8 @@ public class WebSocketClientHandshakerFactory {
* Instances a new handshaker * Instances a new handshaker
* *
* @param webSocketURL * @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* Subsequent web socket frames will be sent to this URL. * sent to this URL.
* @param version * @param version
* Version of web socket specification to use to connect to the server * Version of web socket specification to use to connect to the server
* @param subprotocol * @param subprotocol
@ -59,24 +59,20 @@ public class WebSocketClientHandshakerFactory {
* @param customHeaders * @param customHeaders
* Custom HTTP headers to send during the handshake * Custom HTTP headers to send during the handshake
* @param maxFramePayloadLength * @param maxFramePayloadLength
* Maximum allowable frame payload length. Setting this value to your application's * Maximum allowable frame payload length. Setting this value to your application's requirement may
* requirement may reduce denial of service attacks using long data frames. * reduce denial of service attacks using long data frames.
* @throws WebSocketHandshakeException
*/ */
public WebSocketClientHandshaker newHandshaker( public WebSocketClientHandshaker newHandshaker(URI webSocketURL, WebSocketVersion version, String subprotocol,
URI webSocketURL, WebSocketVersion version, String subprotocol, boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength) throws WebSocketHandshakeException {
boolean allowExtensions, Map<String, String> customHeaders, long maxFramePayloadLength)
throws WebSocketHandshakeException {
if (version == WebSocketVersion.V13) { if (version == WebSocketVersion.V13) {
return new WebSocketClientHandshaker13( return new WebSocketClientHandshaker13(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
} }
if (version == WebSocketVersion.V08) { if (version == WebSocketVersion.V08) {
return new WebSocketClientHandshaker08( return new WebSocketClientHandshaker08(webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
webSocketURL, version, subprotocol, allowExtensions, customHeaders, maxFramePayloadLength);
} }
if (version == WebSocketVersion.V00) { if (version == WebSocketVersion.V00) {
return new WebSocketClientHandshaker00( return new WebSocketClientHandshaker00(webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
webSocketURL, version, subprotocol, customHeaders, maxFramePayloadLength);
} }
throw new WebSocketHandshakeException("Protocol version " + version.toString() + " not supported."); throw new WebSocketHandshakeException("Protocol version " + version.toString() + " not supported.");

View File

@ -67,8 +67,8 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
* Constructor specifying the destination web socket location * Constructor specifying the destination web socket location
* *
* @param webSocketURL * @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* Subsequent web socket frames will be sent to this URL. * sent to this URL.
* @param subprotocols * @param subprotocols
* CSV of supported protocols * CSV of supported protocols
* @param maxFramePayloadLength * @param maxFramePayloadLength

View File

@ -52,15 +52,15 @@ public class WebSocketServerHandshakerFactory {
* Constructor * Constructor
* *
* @param webSocketURL * @param webSocketURL
* URL for web socket communications. e.g "ws://myhost.com/mypath". * URL for web socket communications. e.g "ws://myhost.com/mypath". Subsequent web socket frames will be
* Subsequent web socket frames will be sent to this URL. * sent to this URL.
* @param subprotocols * @param subprotocols
* CSV of supported protocols. Null if sub protocols not supported. * CSV of supported protocols. Null if sub protocols not supported.
* @param allowExtensions * @param allowExtensions
* Allow extensions to be used in the reserved bits of the web socket frame * Allow extensions to be used in the reserved bits of the web socket frame
* @param maxFramePayloadLength * @param maxFramePayloadLength
* Maximum allowable frame payload length. Setting this value to your application's * Maximum allowable frame payload length. Setting this value to your application's requirement may
* requirement may reduce denial of service attacks using long data frames. * reduce denial of service attacks using long data frames.
*/ */
public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions, public WebSocketServerHandshakerFactory(String webSocketURL, String subprotocols, boolean allowExtensions,
long maxFramePayloadLength) { long maxFramePayloadLength) {
@ -73,8 +73,8 @@ public class WebSocketServerHandshakerFactory {
/** /**
* Instances a new handshaker * Instances a new handshaker
* *
* @return A new WebSocketServerHandshaker for the requested web socket version. Null if web * @return A new WebSocketServerHandshaker for the requested web socket version. Null if web socket version is not
* socket version is not supported. * supported.
*/ */
public WebSocketServerHandshaker newHandshaker(HttpRequest req) { public WebSocketServerHandshaker newHandshaker(HttpRequest req) {
@ -82,19 +82,16 @@ public class WebSocketServerHandshakerFactory {
if (version != null) { if (version != null) {
if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) { if (version.equals(WebSocketVersion.V13.toHttpHeaderValue())) {
// Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification). // Version 13 of the wire protocol - RFC 6455 (version 17 of the draft hybi specification).
return new WebSocketServerHandshaker13( return new WebSocketServerHandshaker13(webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
} else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) { } else if (version.equals(WebSocketVersion.V08.toHttpHeaderValue())) {
// Version 8 of the wire protocol - version 10 of the draft hybi specification. // Version 8 of the wire protocol - version 10 of the draft hybi specification.
return new WebSocketServerHandshaker08( return new WebSocketServerHandshaker08(webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
webSocketURL, subprotocols, allowExtensions, maxFramePayloadLength);
} else { } else {
return null; return null;
} }
} else { } else {
// Assume version 00 where version header was not specified // Assume version 00 where version header was not specified
return new WebSocketServerHandshaker00( return new WebSocketServerHandshaker00(webSocketURL, subprotocols, maxFramePayloadLength);
webSocketURL, subprotocols, maxFramePayloadLength);
} }
} }

View File

@ -21,10 +21,9 @@
* This package supports different web socket specification versions (hence the X suffix). * This package supports different web socket specification versions (hence the X suffix).
* The specification current supported are: * The specification current supported are:
* <ul> * <ul>
* <li><a href="http://goo.gl/wFiu3">draft-ietf-hybi-thewebsocketprotocol-00</a></li> * <li><a href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00">draft-ietf-hybi-thewebsocketprotocol-00</a></li>
* <li><a href="http://goo.gl/h27VE">draft-ietf-hybi-thewebsocketprotocol-10</a></li> * <li><a href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10">draft-ietf-hybi-thewebsocketprotocol-10</a></li>
* <li><a href="http://tools.ietf.org/html/rfc6455 ">RFC 6455</a> (originally * <li><a href="http://tools.ietf.org/html/rfc6455 ">RFC 6455</a> (originally <a href="http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17">draft-ietf-hybi-thewebsocketprotocol-17</a>)</li>
* <a href="http://goo.gl/zVBkL">draft-ietf-hybi-thewebsocketprotocol-17</a>)</li>
* </ul> * </ul>
* </p> * </p>
* <p> * <p>

View File

@ -42,15 +42,12 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder<VoidEnum> {
/** /**
* Create a new instance of {@link CompatibleMarshallingDecoder}. * Create a new instance of {@link CompatibleMarshallingDecoder}.
* *
* @param provider * @param provider the {@link UnmarshallerProvider} which is used to obtain the {@link Unmarshaller} for the {@link Channel}
* the {@link UnmarshallerProvider} which is used to obtain the {@link Unmarshaller} * @param maxObjectSize the maximal size (in bytes) of the {@link Object} to unmarshal. Once the size is exceeded
* for the {@link Channel} * the {@link Channel} will get closed. Use a a maxObjectSize of {@link Integer#MAX_VALUE} to disable this.
* @param maxObjectSize * You should only do this if you are sure that the received Objects will never be big and the
* the maximal size (in bytes) of the {@link Object} to unmarshal. Once the size is * sending side are trusted, as this opens the possibility for a DOS-Attack due an {@link OutOfMemoryError}.
* 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) { public CompatibleMarshallingDecoder(UnmarshallerProvider provider, int maxObjectSize) {
this.provider = provider; this.provider = provider;
@ -58,8 +55,7 @@ public class CompatibleMarshallingDecoder extends ReplayingDecoder<VoidEnum> {
} }
@Override @Override
protected Object decode( protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, VoidEnum state) throws Exception {
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, VoidEnum state) throws Exception {
Unmarshaller unmarshaller = provider.getUnmarshaller(ctx); Unmarshaller unmarshaller = provider.getUnmarshaller(ctx);
ByteInput input = new ChannelBufferByteInput(buffer); ByteInput input = new ChannelBufferByteInput(buffer);
if (maxObjectSize != Integer.MAX_VALUE) { if (maxObjectSize != Integer.MAX_VALUE) {

View File

@ -50,8 +50,7 @@ public class CompatibleMarshallingEncoder extends OneToOneEncoder {
@Override @Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
Marshaller marshaller = provider.getMarshaller(ctx); Marshaller marshaller = provider.getMarshaller(ctx);
ChannelBufferByteOutput output = ChannelBufferByteOutput output = new ChannelBufferByteOutput(ctx.getChannel().getConfig().getBufferFactory(), 256);
new ChannelBufferByteOutput(ctx.getChannel().getConfig().getBufferFactory(), 256);
marshaller.start(output); marshaller.start(output);
marshaller.writeObject(msg); marshaller.writeObject(msg);
marshaller.finish(); marshaller.finish();
@ -59,4 +58,5 @@ public class CompatibleMarshallingEncoder extends OneToOneEncoder {
return output.getBuffer(); return output.getBuffer();
} }
} }

View File

@ -27,8 +27,7 @@ import org.jboss.netty.handler.codec.frame.TooLongFrameException;
/** /**
* Decoder which MUST be used with {@link MarshallingEncoder}. * Decoder which MUST be used with {@link MarshallingEncoder}.
* *
* A {@link LengthFieldBasedFrameDecoder} which use an {@link Unmarshaller} to read the Object out * A {@link LengthFieldBasedFrameDecoder} which use an {@link Unmarshaller} to read the Object out of the {@link ChannelBuffer}.
* of the {@link ChannelBuffer}.
* *
*/ */
public class MarshallingDecoder extends LengthFieldBasedFrameDecoder { public class MarshallingDecoder extends LengthFieldBasedFrameDecoder {
@ -78,8 +77,8 @@ public class MarshallingDecoder extends LengthFieldBasedFrameDecoder {
unmarshaller.finish(); unmarshaller.finish();
return obj; return obj;
} finally { } finally {
// Call close in a finally block as the ReplayingDecoder will throw an Error if not // Call close in a finally block as the ReplayingDecoder will throw an Error if not enough bytes are
// enough bytes are readable. This helps to be sure that we do not leak resource // readable. This helps to be sure that we do not leak resource
unmarshaller.close(); unmarshaller.close();
} }
} }

View File

@ -75,8 +75,7 @@ public class MarshallingEncoder extends OneToOneEncoder {
@Override @Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
Marshaller marshaller = provider.getMarshaller(ctx); Marshaller marshaller = provider.getMarshaller(ctx);
ChannelBufferByteOutput output = new ChannelBufferByteOutput( ChannelBufferByteOutput output = new ChannelBufferByteOutput(ctx.getChannel().getConfig().getBufferFactory(), estimatedLength);
ctx.getChannel().getConfig().getBufferFactory(), estimatedLength);
output.getBuffer().writeBytes(LENGTH_PLACEHOLDER); output.getBuffer().writeBytes(LENGTH_PLACEHOLDER);
marshaller.start(output); marshaller.start(output);
marshaller.writeObject(msg); marshaller.writeObject(msg);

View File

@ -389,9 +389,8 @@ public abstract class ReplayingDecoder<T extends Enum<T>>
} }
/** /**
* Calls {@link #decode(ChannelHandlerContext, Channel, ChannelBuffer, Enum)}. This method * Calls {@link #decode(ChannelHandlerContext, Channel, ChannelBuffer, Enum)}. This method should be never used by {@link ReplayingDecoder} itself.
* should be never used by {@link ReplayingDecoder} itself. But to be safe we should handle it * But to be safe we should handle it anyway
* anyway
*/ */
@Override @Override
protected final Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { protected final Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
@ -521,9 +520,7 @@ public abstract class ReplayingDecoder<T extends Enum<T>>
} }
} }
private void callDecode( private void callDecode(ChannelHandlerContext context, Channel channel, ChannelBuffer input, ChannelBuffer replayableInput, SocketAddress remoteAddress) throws Exception {
ChannelHandlerContext context, Channel channel,
ChannelBuffer input, ChannelBuffer replayableInput, SocketAddress remoteAddress) throws Exception {
while (input.readable()) { while (input.readable()) {
int oldReaderIndex = checkpoint = input.readerIndex(); int oldReaderIndex = checkpoint = input.readerIndex();
Object result = null; Object result = null;

View File

@ -27,11 +27,10 @@ import org.jboss.netty.handler.codec.http.HttpMethod;
public final class RtspMethods { public final class RtspMethods {
/** /**
* The OPTIONS method represents a request for information about the communication options * The OPTIONS method represents a request for information about the communication options available on the request/response
* available on the request/response chain identified by the Request-URI. This method allows * chain identified by the Request-URI. This method allows the client to determine the options and/or requirements
* the client to determine the options and/or requirements associated with a resource, or the * associated with a resource, or the capabilities of a server, without implying a resource action or initiating a
* capabilities of a server, without implying a resource action or initiating a resource * resource retrieval.
* retrieval.
*/ */
public static final HttpMethod OPTIONS = HttpMethod.OPTIONS; public static final HttpMethod OPTIONS = HttpMethod.OPTIONS;

View File

@ -107,8 +107,7 @@ public final class RtspResponseStatuses {
/** /**
* 407 Proxy Authentication Required * 407 Proxy Authentication Required
*/ */
public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = public static final HttpResponseStatus PROXY_AUTHENTICATION_REQUIRED = HttpResponseStatus.PROXY_AUTHENTICATION_REQUIRED;
HttpResponseStatus.PROXY_AUTHENTICATION_REQUIRED;
/** /**
* 408 Request Timeout * 408 Request Timeout

View File

@ -38,9 +38,7 @@ public final class ClassResolvers {
* @return new instance of class resolver * @return new instance of class resolver
*/ */
public static ClassResolver weakCachingResolver(ClassLoader classLoader) { public static ClassResolver weakCachingResolver(ClassLoader classLoader) {
return new CachingClassResolver( return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new WeakReferenceMap<String, Class<?>>(new HashMap<String, Reference<Class<?>>>()));
new ClassLoaderClassResolver(defaultClassLoader(classLoader)),
new WeakReferenceMap<String, Class<?>>(new HashMap<String, Reference<Class<?>>>()));
} }
/** /**
@ -51,9 +49,7 @@ public final class ClassResolvers {
* @return new instance of class resolver * @return new instance of class resolver
*/ */
public static ClassResolver softCachingResolver(ClassLoader classLoader) { public static ClassResolver softCachingResolver(ClassLoader classLoader) {
return new CachingClassResolver( return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new SoftReferenceMap<String, Class<?>>(new HashMap<String, Reference<Class<?>>>()));
new ClassLoaderClassResolver(defaultClassLoader(classLoader)),
new SoftReferenceMap<String, Class<?>>(new HashMap<String, Reference<Class<?>>>()));
} }
/** /**
@ -64,9 +60,7 @@ public final class ClassResolvers {
* @return new instance of class resolver * @return new instance of class resolver
*/ */
public static ClassResolver weakCachingConcurrentResolver(ClassLoader classLoader) { public static ClassResolver weakCachingConcurrentResolver(ClassLoader classLoader) {
return new CachingClassResolver( return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new WeakReferenceMap<String, Class<?>>(new ConcurrentHashMap<String, Reference<Class<?>>>()));
new ClassLoaderClassResolver(defaultClassLoader(classLoader)),
new WeakReferenceMap<String, Class<?>>(new ConcurrentHashMap<String, Reference<Class<?>>>()));
} }
/** /**
@ -77,9 +71,7 @@ public final class ClassResolvers {
* @return new instance of class resolver * @return new instance of class resolver
*/ */
public static ClassResolver softCachingConcurrentResolver(ClassLoader classLoader) { public static ClassResolver softCachingConcurrentResolver(ClassLoader classLoader) {
return new CachingClassResolver( return new CachingClassResolver(new ClassLoaderClassResolver(defaultClassLoader(classLoader)), new SoftReferenceMap<String, Class<?>>(new ConcurrentHashMap<String, Reference<Class<?>>>()));
new ClassLoaderClassResolver(defaultClassLoader(classLoader)),
new SoftReferenceMap<String, Class<?>>(new ConcurrentHashMap<String, Reference<Class<?>>>()));
} }
static ClassLoader defaultClassLoader(ClassLoader classLoader) { static ClassLoader defaultClassLoader(ClassLoader classLoader) {

View File

@ -74,8 +74,7 @@ public class CompatibleObjectDecoder extends ReplayingDecoder<CompatibleObjectDe
@Override @Override
protected Object decode( protected Object decode(
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, CompatibleObjectDecoderState state) throws Exception {
CompatibleObjectDecoderState state) throws Exception {
bin.switchStream(new ChannelBufferInputStream(buffer)); bin.switchStream(new ChannelBufferInputStream(buffer));
switch (state) { switch (state) {
case READ_HEADER: case READ_HEADER:

View File

@ -97,8 +97,7 @@ public class ObjectDecoder extends LengthFieldBasedFrameDecoder {
/** /**
* Create a new decoder with the specified maximum object size and the {@link ClassLoader} * Create a new decoder with the specified maximum object size and the {@link ClassLoader} wrapped in {@link ClassResolvers#weakCachingResolver(ClassLoader)}
* wrapped in {@link ClassResolvers#weakCachingResolver(ClassLoader)}.
* *
* @param maxObjectSize the maximum byte length of the serialized object. * @param maxObjectSize the maximum byte length of the serialized object.
* if the length of the received object is greater * if the length of the received object is greater

View File

@ -280,8 +280,7 @@ public class SpdyHttpEncoder implements ChannelDownstreamHandler {
httpMessage.removeHeader("Proxy-Connection"); httpMessage.removeHeader("Proxy-Connection");
httpMessage.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING); httpMessage.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING);
SpdySynStreamFrame spdySynStreamFrame = SpdySynStreamFrame spdySynStreamFrame = new DefaultSpdySynStreamFrame(streamID, associatedToStreamID, priority);
new DefaultSpdySynStreamFrame(streamID, associatedToStreamID, priority);
// Unfold the first line of the message into name/value pairs // Unfold the first line of the message into name/value pairs
if (httpMessage instanceof HttpRequest) { if (httpMessage instanceof HttpRequest) {

View File

@ -479,8 +479,7 @@ public class SpdySessionHandler extends SimpleChannelUpstreamHandler
e.getFuture().addListener(new ChannelFutureListener() { e.getFuture().addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) { if (!future.isSuccess()) {
issueStreamError( issueStreamError(context, remoteAddress, streamID, SpdyStreamStatus.INTERNAL_ERROR);
context, remoteAddress, streamID, SpdyStreamStatus.INTERNAL_ERROR);
} }
} }
}); });
@ -505,8 +504,7 @@ public class SpdySessionHandler extends SimpleChannelUpstreamHandler
e.getFuture().addListener(new ChannelFutureListener() { e.getFuture().addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception { public void operationComplete(ChannelFuture future) throws Exception {
if (!future.isSuccess()) { if (!future.isSuccess()) {
issueStreamError( issueStreamError(context, remoteAddress, streamID, SpdyStreamStatus.INTERNAL_ERROR);
context, remoteAddress, streamID, SpdyStreamStatus.INTERNAL_ERROR);
} }
} }
}); });
@ -739,8 +737,7 @@ public class SpdySessionHandler extends SimpleChannelUpstreamHandler
return false; return false;
} }
spdySession.acceptStream( spdySession.acceptStream(
streamID, priority, remoteSideClosed, localSideClosed, streamID, priority, remoteSideClosed, localSideClosed, initialSendWindowSize, initialReceiveWindowSize);
initialSendWindowSize, initialReceiveWindowSize);
if (isRemoteInitiatedID(streamID)) { if (isRemoteInitiatedID(streamID)) {
lastGoodStreamID = streamID; lastGoodStreamID = streamID;
} }

View File

@ -1,86 +1,83 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.handler.execution; package org.jboss.netty.handler.execution;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import org.jboss.netty.util.ExternalResourceReleasable; import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.internal.ExecutorUtil; import org.jboss.netty.util.internal.ExecutorUtil;
/** /**
* A special {@link Executor} which allows to chain a series of * A special {@link Executor} which allows to chain a series of
* {@link Executor}s and {@link ChannelEventRunnableFilter}. * {@link Executor}s and {@link ChannelEventRunnableFilter}.
*/ */
public class ChainedExecutor implements Executor, ExternalResourceReleasable { public class ChainedExecutor implements Executor, ExternalResourceReleasable {
private final Executor cur; private final Executor cur;
private final Executor next; private final Executor next;
private final ChannelEventRunnableFilter filter; private final ChannelEventRunnableFilter filter;
/** /**
* Create a new {@link ChainedExecutor} which will used the given * Create a new {@link ChainedExecutor} which will used the given {@link ChannelEventRunnableFilter} to see if the {@link #cur} {@link Executor} should get used.
* {@link ChannelEventRunnableFilter} to see if the {@link #cur} {@link Executor} should get * Otherwise it will pass the work to the {@link #next} {@link Executor}
* used. Otherwise it will pass the work to the {@link #next} {@link Executor} *
* * @param filter the {@link ChannelEventRunnableFilter} which will be used to check if the {@link ChannelEventRunnable} should be passed to the cur or next {@link Executor}
* @param filter the {@link ChannelEventRunnableFilter} which will be used to check if the * @param cur the {@link Executor} to use if the {@link ChannelEventRunnableFilter} match
* {@link ChannelEventRunnable} should be passed to the cur or next {@link Executor} * @param next the {@link Executor} to use if the {@link ChannelEventRunnableFilter} does not match
* @param cur the {@link Executor} to use if the {@link ChannelEventRunnableFilter} match */
* @param next the {@link Executor} to use if the {@link ChannelEventRunnableFilter} does not match public ChainedExecutor(ChannelEventRunnableFilter filter, Executor cur, Executor next) {
*/ if (filter == null) {
public ChainedExecutor(ChannelEventRunnableFilter filter, Executor cur, Executor next) { throw new NullPointerException("filter");
if (filter == null) { }
throw new NullPointerException("filter"); if (cur == null) {
} throw new NullPointerException("cur");
if (cur == null) { }
throw new NullPointerException("cur"); if (next == null) {
} throw new NullPointerException("next");
if (next == null) { }
throw new NullPointerException("next");
} this.filter = filter;
this.cur = cur;
this.filter = filter; this.next = next;
this.cur = cur; }
this.next = next;
} /**
* Execute the passed {@link ChannelEventRunnable} with the current {@link Executor} if the {@link ChannelEventRunnableFilter} match.
/** * Otherwise pass it to the next {@link Executor} in the chain.
* Execute the passed {@link ChannelEventRunnable} with the current {@link Executor} if the */
* {@link ChannelEventRunnableFilter} match. Otherwise pass it to the next {@link Executor} in public void execute(Runnable command) {
* the chain. assert command instanceof ChannelEventRunnable;
*/ if (filter.filter((ChannelEventRunnable) command)) {
public void execute(Runnable command) { cur.execute(command);
assert command instanceof ChannelEventRunnable; } else {
if (filter.filter((ChannelEventRunnable) command)) { next.execute(command);
cur.execute(command); }
} else { }
next.execute(command);
} public void releaseExternalResources() {
} ExecutorUtil.terminate(cur, next);
releaseExternal(cur);
public void releaseExternalResources() { releaseExternal(next);
ExecutorUtil.terminate(cur, next); }
releaseExternal(cur);
releaseExternal(next);
} private static void releaseExternal(Executor executor) {
if (executor instanceof ExternalResourceReleasable) {
((ExternalResourceReleasable) executor).releaseExternalResources();
private static void releaseExternal(Executor executor) { }
if (executor instanceof ExternalResourceReleasable) { }
((ExternalResourceReleasable) executor).releaseExternalResources(); }
}
}
}

View File

@ -16,8 +16,6 @@
package org.jboss.netty.handler.execution; package org.jboss.netty.handler.execution;
import java.util.concurrent.Executor;
import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelHandlerContext;
@ -26,15 +24,14 @@ import org.jboss.netty.channel.ChannelHandlerContext;
*/ */
public class ChannelDownstreamEventRunnable extends ChannelEventRunnable { public class ChannelDownstreamEventRunnable extends ChannelEventRunnable {
public ChannelDownstreamEventRunnable(ChannelHandlerContext ctx, ChannelEvent e, Executor executor) { public ChannelDownstreamEventRunnable(ChannelHandlerContext ctx, ChannelEvent e) {
super(ctx, e, executor); super(ctx, e);
} }
/** /**
* Send the {@link ChannelEvent} downstream * Send the {@link ChannelEvent} downstream
*/ */
@Override public void run() {
protected void doRun() {
ctx.sendDownstream(e); ctx.sendDownstream(e);
} }
} }

View File

@ -1,27 +1,27 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.handler.execution; package org.jboss.netty.handler.execution;
/** /**
* {@link ChannelEventRunnableFilter} implementation which matches {@link ChannelDownstreamEventRunnable} * {@link ChannelEventRunnableFilter} implementation which matches {@link ChannelDownstreamEventRunnable}
* *
*/ */
public class ChannelDownstreamEventRunnableFilter implements ChannelEventRunnableFilter { public class ChannelDownstreamEventRunnableFilter implements ChannelEventRunnableFilter {
public boolean filter(ChannelEventRunnable event) { public boolean filter(ChannelEventRunnable event) {
return event instanceof ChannelDownstreamEventRunnable; return event instanceof ChannelDownstreamEventRunnable;
} }
} }

View File

@ -1,72 +1,55 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.handler.execution; package org.jboss.netty.handler.execution;
import java.util.concurrent.Executor; import org.jboss.netty.channel.ChannelEvent;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelEvent; import org.jboss.netty.util.EstimatableObjectWrapper;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.util.EstimatableObjectWrapper; public abstract class ChannelEventRunnable implements Runnable, EstimatableObjectWrapper {
import org.jboss.netty.util.internal.DeadLockProofWorker;
protected final ChannelHandlerContext ctx;
public abstract class ChannelEventRunnable implements Runnable, EstimatableObjectWrapper { protected final ChannelEvent e;
int estimatedSize;
protected final ChannelHandlerContext ctx;
protected final ChannelEvent e; /**
int estimatedSize; * Creates a {@link Runnable} which sends the specified {@link ChannelEvent}
private final Executor executor; * upstream via the specified {@link ChannelHandlerContext}.
*/
/** public ChannelEventRunnable(ChannelHandlerContext ctx, ChannelEvent e) {
* Creates a {@link Runnable} which sends the specified {@link ChannelEvent} this.ctx = ctx;
* upstream via the specified {@link ChannelHandlerContext}. this.e = e;
*/ }
public ChannelEventRunnable(ChannelHandlerContext ctx, ChannelEvent e, Executor executor) {
this.ctx = ctx; /**
this.e = e; * Returns the {@link ChannelHandlerContext} which will be used to
this.executor = executor; * send the {@link ChannelEvent} upstream.
} */
public ChannelHandlerContext getContext() {
/** return ctx;
* Returns the {@link ChannelHandlerContext} which will be used to }
* send the {@link ChannelEvent} upstream.
*/ /**
public ChannelHandlerContext getContext() { * Returns the {@link ChannelEvent} which will be sent upstream.
return ctx; */
} public ChannelEvent getEvent() {
return e;
/** }
* Returns the {@link ChannelEvent} which will be sent upstream.
*/ public Object unwrap() {
public ChannelEvent getEvent() { return e;
return e; }
} }
public Object unwrap() {
return e;
}
public final void run() {
try {
DeadLockProofWorker.PARENT.set(executor);
doRun();
} finally {
DeadLockProofWorker.PARENT.remove();
}
}
protected abstract void doRun();
}

View File

@ -1,27 +1,27 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.handler.execution; package org.jboss.netty.handler.execution;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
public interface ChannelEventRunnableFilter { public interface ChannelEventRunnableFilter {
/** /**
* Return <code>true</code> if the {@link ChannelEventRunnable} should get handled by the {@link Executor} * Return <code>true</code> if the {@link ChannelEventRunnable} should get handled by the {@link Executor}
* *
*/ */
boolean filter(ChannelEventRunnable event); boolean filter(ChannelEventRunnable event);
} }

View File

@ -32,16 +32,15 @@ public class ChannelUpstreamEventRunnable extends ChannelEventRunnable {
* Creates a {@link Runnable} which sends the specified {@link ChannelEvent} * Creates a {@link Runnable} which sends the specified {@link ChannelEvent}
* upstream via the specified {@link ChannelHandlerContext}. * upstream via the specified {@link ChannelHandlerContext}.
*/ */
public ChannelUpstreamEventRunnable(ChannelHandlerContext ctx, ChannelEvent e, Executor executor) { public ChannelUpstreamEventRunnable(ChannelHandlerContext ctx, ChannelEvent e) {
super(ctx, e, executor); super(ctx, e);
} }
/** /**
* Sends the event upstream. * Sends the event upstream.
*/ */
@Override public void run() {
protected void doRun() {
ctx.sendUpstream(e); ctx.sendUpstream(e);
} }
} }

View File

@ -1,25 +1,25 @@
/* /*
* Copyright 2012 The Netty Project * Copyright 2012 The Netty Project
* *
* The Netty Project licenses this file to you under the Apache License, * 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 * 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: * with the License. You may obtain a copy of the License at:
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jboss.netty.handler.execution; package org.jboss.netty.handler.execution;
/** /**
* {@link ChannelEventRunnableFilter} which matches {@link ChannelDownstreamEventRunnable} * {@link ChannelEventRunnableFilter} which matches {@link ChannelDownstreamEventRunnable}
*/ */
public class ChannelUpstreamEventRunnableFilter implements ChannelEventRunnableFilter { public class ChannelUpstreamEventRunnableFilter implements ChannelEventRunnableFilter {
public boolean filter(ChannelEventRunnable event) { public boolean filter(ChannelEventRunnable event) {
return event instanceof ChannelDownstreamEventRunnable; return event instanceof ChannelDownstreamEventRunnable;
} }
} }

View File

@ -169,7 +169,7 @@ public class ExecutionHandler implements ChannelUpstreamHandler, ChannelDownstre
public void handleUpstream( public void handleUpstream(
ChannelHandlerContext context, ChannelEvent e) throws Exception { ChannelHandlerContext context, ChannelEvent e) throws Exception {
if (handleUpstream) { if (handleUpstream) {
executor.execute(new ChannelUpstreamEventRunnable(context, e, executor)); executor.execute(new ChannelUpstreamEventRunnable(context, e));
} else { } else {
context.sendUpstream(e); context.sendUpstream(e);
} }
@ -180,7 +180,7 @@ public class ExecutionHandler implements ChannelUpstreamHandler, ChannelDownstre
// check if the read was suspend // check if the read was suspend
if (!handleReadSuspend(ctx, e)) { if (!handleReadSuspend(ctx, e)) {
if (handleDownstream) { if (handleDownstream) {
executor.execute(new ChannelDownstreamEventRunnable(ctx, e, executor)); executor.execute(new ChannelDownstreamEventRunnable(ctx, e));
} else { } else {
ctx.sendDownstream(e); ctx.sendDownstream(e);
} }

View File

@ -182,9 +182,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
int corePoolSize, long maxChannelMemorySize, long maxTotalMemorySize, int corePoolSize, long maxChannelMemorySize, long maxTotalMemorySize,
long keepAliveTime, TimeUnit unit) { long keepAliveTime, TimeUnit unit) {
this( this(corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit, Executors.defaultThreadFactory());
corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit,
Executors.defaultThreadFactory());
} }
/** /**
@ -203,9 +201,7 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
int corePoolSize, long maxChannelMemorySize, long maxTotalMemorySize, int corePoolSize, long maxChannelMemorySize, long maxTotalMemorySize,
long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) { long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) {
this( this(corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit, new DefaultObjectSizeEstimator(), threadFactory);
corePoolSize, maxChannelMemorySize, maxTotalMemorySize, keepAliveTime, unit,
new DefaultObjectSizeEstimator(), threadFactory);
} }
/** /**
@ -281,13 +277,11 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
} }
/** /**
* See {@link ThreadPoolExecutor#shutdownNow()} for how it handles the shutdown. * See {@link ThreadPoolExecutor#shutdownNow()} for how it handles the shutdown. If <code>true</code> is given to this method it also notifies all {@link ChannelFuture}'s
* If <code>true</code> is given to this method it also notifies all {@link ChannelFuture}'s
* of the not executed {@link ChannelEventRunnable}'s. * of the not executed {@link ChannelEventRunnable}'s.
* *
* <p> * <p>
* Be aware that if you call this with <code>false</code> you will need to handle the * Be aware that if you call this with <code>false</code> you will need to handle the notification of the {@link ChannelFuture}'s by your self. So only use this if you
* notification of the {@link ChannelFuture}'s by your self. So only use this if you
* really have a use-case for it. * really have a use-case for it.
* </p> * </p>
* *
@ -401,13 +395,11 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
} }
/** /**
* If set to <code>false</code> no queued {@link ChannelEventRunnable}'s {@link ChannelFuture} * If set to <code>false</code> no queued {@link ChannelEventRunnable}'s {@link ChannelFuture} will get notified once {@link #shutdownNow()} is called.
* will get notified once {@link #shutdownNow()} is called. If set to <code>true</code> every * If set to <code>true</code> every queued {@link ChannelEventRunnable} will get marked as failed via {@link ChannelFuture#setFailure(Throwable)}.
* queued {@link ChannelEventRunnable} will get marked as failed via {@link ChannelFuture#setFailure(Throwable)}.
* *
* <p> * <p>
* Please only set this to <code>false</code> if you want to handle the notification by yourself * Please only set this to <code>false</code> if you want to handle the notification by yourself and know what you are doing. Default is <code>true</code>.
* and know what you are doing. Default is <code>true</code>.
* </p> * </p>
*/ */
public void setNotifyChannelFuturesOnShutdown(boolean notifyOnShutdown) { public void setNotifyChannelFuturesOnShutdown(boolean notifyOnShutdown) {
@ -415,8 +407,8 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
} }
/** /**
* Returns if the {@link ChannelFuture}'s of the {@link ChannelEventRunnable}'s should be * Returns if the {@link ChannelFuture}'s of the {@link ChannelEventRunnable}'s should be notified about the shutdown of this {@link MemoryAwareThreadPoolExecutor}.
* notified about the shutdown of this {@link MemoryAwareThreadPoolExecutor}. *
*/ */
public boolean getNotifyChannelFuturesOnShutdown() { public boolean getNotifyChannelFuturesOnShutdown() {
return notifyOnShutdown; return notifyOnShutdown;
@ -532,9 +524,8 @@ public class MemoryAwareThreadPoolExecutor extends ThreadPoolExecutor {
//System.out.println("READABLE"); //System.out.println("READABLE");
ChannelHandlerContext ctx = eventTask.getContext(); ChannelHandlerContext ctx = eventTask.getContext();
if (ctx.getHandler() instanceof ExecutionHandler) { if (ctx.getHandler() instanceof ExecutionHandler) {
// check if the attachment was set as this means that we suspend the channel // check if the attachment was set as this means that we suspend the channel from reads. This only works when
// from reads. This only works when this pool is used with ExecutionHandler // this pool is used with ExecutionHandler but I guess thats good enough for us.
// but I guess thats good enough for us.
// //
// See #215 // See #215
if (ctx.getAttachment() != null) { if (ctx.getAttachment() != null) {

View File

@ -28,13 +28,13 @@ import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.util.ObjectSizeEstimator; import org.jboss.netty.util.ObjectSizeEstimator;
/** /**
* {@link Executor} which should be used for downstream {@link ChannelEvent}'s. This implementation * {@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}.
* will take care of preserve the order of the events in a {@link Channel}. If you don't need to * 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}.
* preserve the order just use one of the {@link Executor} implementations provided by the static
* methods of {@link Executors}.
* <br> * <br>
* <br> * <br>
*
* For more informations about how the order is preserved see {@link OrderedMemoryAwareThreadPoolExecutor} * For more informations about how the order is preserved see {@link OrderedMemoryAwareThreadPoolExecutor}
*
*/ */
public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwareThreadPoolExecutor { public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwareThreadPoolExecutor {
@ -83,8 +83,7 @@ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwar
} }
/** /**
* Throws {@link UnsupportedOperationException} as there is not support for limit the memory * Throws {@link UnsupportedOperationException} as there is not support for limit the memory size in this implementation
* size in this implementation
*/ */
@Override @Override
public void setObjectSizeEstimator(ObjectSizeEstimator objectSizeEstimator) { public void setObjectSizeEstimator(ObjectSizeEstimator objectSizeEstimator) {
@ -100,8 +99,7 @@ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwar
} }
/** /**
* Throws {@link UnsupportedOperationException} as there is not support for limit the memory * Throws {@link UnsupportedOperationException} as there is not support for limit the memory size in this implementation
* size in this implementation
*/ */
@Override @Override
public void setMaxChannelMemorySize(long maxChannelMemorySize) { public void setMaxChannelMemorySize(long maxChannelMemorySize) {
@ -117,8 +115,7 @@ public final class OrderedDownstreamThreadPoolExecutor extends OrderedMemoryAwar
} }
/** /**
* Throws {@link UnsupportedOperationException} as there is not support for limit the memory * Throws {@link UnsupportedOperationException} as there is not support for limit the memory size in this implementation
* size in this implementation
*/ */
@Override @Override
public void setMaxTotalMemorySize(long maxTotalMemorySize) { public void setMaxTotalMemorySize(long maxTotalMemorySize) {

View File

@ -125,7 +125,7 @@ import org.jboss.netty.util.internal.QueueFactory;
* </pre> * </pre>
* *
* If the expected maximum number of keys is small and deterministic, you could * If the expected maximum number of keys is small and deterministic, you could
* use a weak key map such as <a href="http://goo.gl/TqGl1">ConcurrentWeakHashMap</a> * use a weak key map such as <a href="http://viewvc.jboss.org/cgi-bin/viewvc.cgi/jbosscache/experimental/jsr166/src/jsr166y/ConcurrentWeakHashMap.java?view=markup">ConcurrentWeakHashMap</a>
* or synchronized {@link WeakHashMap} instead of managing the life cycle of the * or synchronized {@link WeakHashMap} instead of managing the life cycle of the
* keys by yourself. * keys by yourself.
* *

View File

@ -30,8 +30,7 @@ import org.jboss.netty.channel.ChannelHandlerContext;
* Implementation of Filter of IP based on ALLOW and DENY rules.<br> * Implementation of Filter of IP based on ALLOW and DENY rules.<br>
* <br><br> * <br><br>
* This implementation could be changed by implementing a new {@link IpFilterRule} than default * This implementation could be changed by implementing a new {@link IpFilterRule} than default
* {@link IpV4SubnetFilterRule} (IPV4 support only), {@link IpSubnetFilterRule} (IPV4 and IPV6 support) * {@link IpV4SubnetFilterRule} (IPV4 support only), {@link IpSubnetFilterRule} (IPV4 and IPV6 support) or {@link IpFilterRule} (IP and host name string pattern support) .<br>
* or {@link IpFilterRule} (IP and host name string pattern support) .<br>
* <br> * <br>
* The check is done by going from step to step in the underlying array of IpFilterRule.<br> * The check is done by going from step to step in the underlying array of IpFilterRule.<br>
* Each {@link IpFilterRule} answers to the method accept if the {@link InetAddress} is accepted or not, * Each {@link IpFilterRule} answers to the method accept if the {@link InetAddress} is accepted or not,

View File

@ -18,20 +18,17 @@
* Implementation of a Ip based Filter handlers.<br> * Implementation of a Ip based Filter handlers.<br>
* <br><br> * <br><br>
* <P>The main goal of this package is to allow to filter connections based on IP rules. * <P>The main goal of this package is to allow to filter connections based on IP rules.
* The main interface is <tt>{@link org.jboss.netty.handler.ipfilter.IpFilteringHandler}</tt> which * The main interface is <tt>{@link org.jboss.netty.handler.ipfilter.IpFilteringHandler}</tt> which all filters will extend.</P>
* all filters will extend.</P>
* *
* <P>Two IP filtering are proposed:<br> * <P>Two IP filtering are proposed:<br>
* <ul> * <ul>
* <li>{@link org.jboss.netty.handler.ipfilter.OneIpFilterHandler}: This filter proposes to allow * <li> <tt>{@link org.jboss.netty.handler.ipfilter.OneIpFilterHandler}</tt>: This filter proposes to allow only one connection by client's IP Address.
* only one connection by client's IP Address. I.E. this filter will prevent two connections * I.E. this filter will prevent two connections from the same client based on its IP address.</li><br><br>
* from the same client based on its IP address.</li><br><br>
* *
* <li>{@link org.jboss.netty.handler.ipfilter.IpFilterRuleHandler}: This filter proposes to allow * <li> <tt>{@link org.jboss.netty.handler.ipfilter.IpFilterRuleHandler}</tt>: This filter proposes to allow or block IP range (based on standard notation
* or block IP range (based on standard notation or on CIDR notation) when the connection is * or on CIDR notation) when the connection is running. It relies on another class like
* running. It relies on another class like <tt>IpV4SubnetFilterRule</tt> (IPV4 support only), * <tt>IpV4SubnetFilterRule</tt> (IPV4 support only), <tt>IpSubnetFilterRule</tt> (IPV4 and IPV6 support) or <tt>PatternRule</tt> (string pattern support)
* <tt>IpSubnetFilterRule</tt> (IPV4 and IPV6 support) or <tt>PatternRule</tt> (string pattern * which implements those Ip ranges.</li><br><br>
* support) which implements those Ip ranges.</li><br><br>
* *
* </ul></P> * </ul></P>
* *
@ -45,32 +42,27 @@
* this method is already implemented.<br> * this method is already implemented.<br>
* <br> * <br>
* *
* <li>handleRefusedChannel method is executed when the accept method filters (blocks, so returning * <li><tt>handleRefusedChannel</tt> method is executed when the accept method filters (blocks, so returning false)
* false) the new connection. This method allows you to implement specific actions to be taken * the new connection. This method allows you to implement specific actions to be taken before the channel is
* before the channel is closed. After this method is called, the channel is immediately closed.</li><br> * closed. After this method is called, the channel is immediately closed.</li><br>
* * So if you want to send back a message to the client, <b>don't forget to return a respectful ChannelFuture,
* So if you want to send back a message to the client, <b>don't forget to return a respectful * otherwise the message could be missed since the channel will be closed immediately after this
* ChannelFuture, otherwise the message could be missed since the channel will be closed immediately * call and the waiting on this channelFuture</b> (at least with respect of asynchronous operations).<br><br>
* after this call and the waiting on this channelFuture</b> (at least with respect of asynchronous * Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener} or returns null if no listener has been set.
* operations).<br><br>
* Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener}
* or returns null if no listener has been set.
* <br><br> * <br><br>
* *
* <li><tt>continues</tt> is called when any event appears after CONNECTED event and only for * <li><tt>continues</tt> is called when any event appears after CONNECTED event and only for
* blocked channels.</li><br> * blocked channels.</li><br>
* It should return True if this new event has to go to next handlers * 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 * 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 * handlers when a channel is blocked. This is intend to prevent any unnecessary action since the connection is refused.<br>
* connection is refused.<br>
* However, you could change its behavior for instance because you don't want that any event * 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.<br> * will be blocked by this filter by returning always true or according to some events.<br>
* <b>Note that OPENED and BOUND events are still passed to the next entry in the pipeline since * <b>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 * 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 * before the CONNECTED event shows up. Therefore, you might want to let CLOSED and UNBOUND be passed
* to the next entry in the pipeline.</b><br><br> * to the next entry in the pipeline.</b><br><br>
* Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener} * Per default implementation this method invokes an {@link org.jboss.netty.handler.ipfilter.IpFilterListener} or returns false if no listener has been set.
* or returns false if no listener has been set.
* <br><br> * <br><br>
* *
* <li>Finally <tt>handleUpstream</tt> traps the CONNECTED and DISCONNECTED events.</li><br> * <li>Finally <tt>handleUpstream</tt> traps the CONNECTED and DISCONNECTED events.</li><br>
@ -78,8 +70,7 @@
* then any new events on this channel will be blocked.<br> * then any new events on this channel will be blocked.<br>
* However, you could change its behavior for instance because you don't want that all events * 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, * will be blocked by this filter by testing the result of isBlocked, and if so,
* calling <tt>ctx.sendUpstream(e);</tt> after calling the super method or by changing the * calling <tt>ctx.sendUpstream(e);</tt> after calling the super method or by changing the <tt>continues</tt> method.<br><br>
* <tt>continues</tt> method.<br><br>
* </ul></P><br><br> * </ul></P><br><br>
* *

View File

@ -219,8 +219,7 @@ public class BlockingReadHandler<E> extends SimpleChannelUpstreamHandler {
* @throws InterruptedException * @throws InterruptedException
* if the operation has been interrupted * if the operation has been interrupted
*/ */
public ChannelEvent readEvent( public ChannelEvent readEvent(long timeout, TimeUnit unit) throws InterruptedException, BlockingReadTimeoutException {
long timeout, TimeUnit unit) throws InterruptedException, BlockingReadTimeoutException {
detectDeadLock(); detectDeadLock();
if (isClosed()) { if (isClosed()) {
if (getQueue().isEmpty()) { if (getQueue().isEmpty()) {

Some files were not shown because too many files have changed in this diff Show More