Revert "Merge branch '3' of ssh://github.com/netty/netty into 3"
This reverts commit7d8a6f9c8e
, reversing changes made to78da141c9d
.
This commit is contained in:
parent
7d8a6f9c8e
commit
91accdc5e4
10
pom.xml
10
pom.xml
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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:
|
||||||
*
|
*
|
||||||
|
@ -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(
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
*
|
*
|
||||||
|
@ -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>
|
||||||
|
@ -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}<Boolean> loggedIn = new {@link ChannelLocal}<>() {
|
* <b>public static final {@link ChannelLocal}<Boolean> loggedIn = new {@link ChannelLocal}<Boolean>() {
|
||||||
* protected Boolean initialValue(Channel channel) {
|
* protected Boolean initialValue(Channel channel) {
|
||||||
* return false;
|
* return false;
|
||||||
* }
|
* }
|
||||||
|
@ -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;
|
||||||
|
@ -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>
|
||||||
*
|
*
|
||||||
|
@ -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>
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)}
|
||||||
*/
|
*/
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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>
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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)}
|
||||||
*/
|
*/
|
||||||
|
@ -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 {
|
||||||
|
@ -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())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>");
|
||||||
|
@ -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() {
|
||||||
|
@ -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());
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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>
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
/**
|
/**
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ import org.jboss.netty.util.CharsetUtil;
|
|||||||
* <pre>
|
* <pre>
|
||||||
* String data = "foobar";
|
* String data = "foobar";
|
||||||
*
|
*
|
||||||
* {@link EncoderEmbedder}<{@link ChannelBuffer}> embedder = new {@link EncoderEmbedder}<>(
|
* {@link EncoderEmbedder}<{@link ChannelBuffer}> embedder = new {@link EncoderEmbedder}<{@link ChannelBuffer}>(
|
||||||
* new {@link Base64Encoder}(), new {@link StringEncoder}());
|
* new {@link Base64Encoder}(), new {@link StringEncoder}());
|
||||||
*
|
*
|
||||||
* embedder.offer(data);
|
* embedder.offer(data);
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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 = ",";
|
||||||
|
|
||||||
|
@ -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)");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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.");
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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();
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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.
|
||||||
*
|
*
|
||||||
|
@ -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,
|
||||||
|
@ -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>
|
||||||
*
|
*
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user