Resurrect channel deregistration and constructor changes
Motivation: Due to the complexity of handling deregistration and re-registration of a channel, we previously decided to remove the deregister() operation completely to simplify our code. However, we realized that it shouldn't be that complicated to implement it during our discussion about making I/O scheduling more flexible and more customizable [1], and thus the removal of deregistration and re-registration is unnecessary now. Modification: - Revert commitc149f4bcc0
- Revert commite743a27e75
- Make some additional adjustments Result: - deregister(), fireChannelUnregistered(), and channelRegistered() were added back.. - Channel constructors do not require an EventLoop anymore. [1] https://github.com/netty/netty/issues/2250
This commit is contained in:
parent
797d6d94a4
commit
48f2e705d9
@ -195,6 +195,14 @@ public class LoggingHandler extends ChannelHandlerAdapter {
|
|||||||
ctx.fireChannelRegistered();
|
ctx.fireChannelRegistered();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
if (logger.isEnabled(internalLevel)) {
|
||||||
|
logger.log(internalLevel, format(ctx, "UNREGISTERED"));
|
||||||
|
}
|
||||||
|
ctx.fireChannelUnregistered();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||||
if (logger.isEnabled(internalLevel)) {
|
if (logger.isEnabled(internalLevel)) {
|
||||||
|
@ -21,7 +21,6 @@ import io.netty.bootstrap.ChannelFactory;
|
|||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.oio.OioEventLoopGroup;
|
import io.netty.channel.oio.OioEventLoopGroup;
|
||||||
@ -109,8 +108,8 @@ public class SocketTestPermutation {
|
|||||||
public Bootstrap newInstance() {
|
public Bootstrap newInstance() {
|
||||||
return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
|
return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
public Channel newChannel(EventLoop loop) {
|
public Channel newChannel() {
|
||||||
return new NioDatagramChannel(loop, InternetProtocolFamily.IPv4);
|
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,12 +32,12 @@ abstract class AbstractEpollChannel extends AbstractChannel {
|
|||||||
volatile int fd;
|
volatile int fd;
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
AbstractEpollChannel(EventLoop eventLoop, int fd, int flag) {
|
AbstractEpollChannel(int fd, int flag) {
|
||||||
this(null, eventLoop, fd, flag, false);
|
this(null, fd, flag, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractEpollChannel(Channel parent, EventLoop eventLoop, int fd, int flag, boolean active) {
|
AbstractEpollChannel(Channel parent, int fd, int flag, boolean active) {
|
||||||
super(parent, eventLoop);
|
super(parent);
|
||||||
this.fd = fd;
|
this.fd = fd;
|
||||||
readFlag = flag;
|
readFlag = flag;
|
||||||
flags |= flag;
|
flags |= flag;
|
||||||
|
@ -23,7 +23,6 @@ import io.netty.channel.ChannelOption;
|
|||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.RecvByteBufAllocator;
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
import io.netty.channel.socket.DatagramChannel;
|
import io.netty.channel.socket.DatagramChannel;
|
||||||
import io.netty.channel.socket.DatagramChannelConfig;
|
import io.netty.channel.socket.DatagramChannelConfig;
|
||||||
@ -51,8 +50,8 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements
|
|||||||
private volatile boolean connected;
|
private volatile boolean connected;
|
||||||
private final EpollDatagramChannelConfig config;
|
private final EpollDatagramChannelConfig config;
|
||||||
|
|
||||||
public EpollDatagramChannel(EventLoop loop) {
|
public EpollDatagramChannel() {
|
||||||
super(loop, Native.socketDgramFd(), Native.EPOLLIN);
|
super(Native.socketDgramFd(), Native.EPOLLIN);
|
||||||
config = new EpollDatagramChannelConfig(this);
|
config = new EpollDatagramChannelConfig(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ import io.netty.channel.ChannelOutboundBuffer;
|
|||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.socket.ServerSocketChannel;
|
import io.netty.channel.socket.ServerSocketChannel;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@ -32,13 +31,11 @@ import java.net.SocketAddress;
|
|||||||
public final class EpollServerSocketChannel extends AbstractEpollChannel implements ServerSocketChannel {
|
public final class EpollServerSocketChannel extends AbstractEpollChannel implements ServerSocketChannel {
|
||||||
|
|
||||||
private final EpollServerSocketChannelConfig config;
|
private final EpollServerSocketChannelConfig config;
|
||||||
private final EventLoopGroup childGroup;
|
|
||||||
private volatile InetSocketAddress local;
|
private volatile InetSocketAddress local;
|
||||||
|
|
||||||
public EpollServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
public EpollServerSocketChannel() {
|
||||||
super(eventLoop, Native.socketStreamFd(), Native.EPOLLACCEPT);
|
super(Native.socketStreamFd(), Native.EPOLLACCEPT);
|
||||||
config = new EpollServerSocketChannelConfig(this);
|
config = new EpollServerSocketChannelConfig(this);
|
||||||
this.childGroup = childGroup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,11 +78,6 @@ public final class EpollServerSocketChannel extends AbstractEpollChannel impleme
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EventLoopGroup childEventLoopGroup() {
|
|
||||||
return childGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
final class EpollServerSocketUnsafe extends AbstractEpollUnsafe {
|
final class EpollServerSocketUnsafe extends AbstractEpollUnsafe {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -109,8 +101,7 @@ public final class EpollServerSocketChannel extends AbstractEpollChannel impleme
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
readPending = false;
|
readPending = false;
|
||||||
pipeline.fireChannelRead(new EpollSocketChannel(EpollServerSocketChannel.this,
|
pipeline.fireChannelRead(new EpollSocketChannel(EpollServerSocketChannel.this, socketFd));
|
||||||
childEventLoopGroup().next(), socketFd));
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// keep on reading as we use epoll ET and need to consume everything from the socket
|
// keep on reading as we use epoll ET and need to consume everything from the socket
|
||||||
pipeline.fireChannelReadComplete();
|
pipeline.fireChannelReadComplete();
|
||||||
|
@ -66,8 +66,8 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
|
|||||||
private volatile boolean inputShutdown;
|
private volatile boolean inputShutdown;
|
||||||
private volatile boolean outputShutdown;
|
private volatile boolean outputShutdown;
|
||||||
|
|
||||||
EpollSocketChannel(Channel parent, EventLoop eventLoop, int fd) {
|
EpollSocketChannel(Channel parent, int fd) {
|
||||||
super(parent, eventLoop, fd, Native.EPOLLIN, true);
|
super(parent, fd, Native.EPOLLIN, true);
|
||||||
config = new EpollSocketChannelConfig(this);
|
config = new EpollSocketChannelConfig(this);
|
||||||
// Directly cache the remote and local addresses
|
// Directly cache the remote and local addresses
|
||||||
// See https://github.com/netty/netty/issues/2359
|
// See https://github.com/netty/netty/issues/2359
|
||||||
@ -75,8 +75,8 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
|
|||||||
local = Native.localAddress(fd);
|
local = Native.localAddress(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EpollSocketChannel(EventLoop eventLoop) {
|
public EpollSocketChannel() {
|
||||||
super(eventLoop, Native.socketStreamFd(), Native.EPOLLIN);
|
super(Native.socketStreamFd(), Native.EPOLLIN);
|
||||||
config = new EpollSocketChannelConfig(this);
|
config = new EpollSocketChannelConfig(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ import io.netty.bootstrap.Bootstrap;
|
|||||||
import io.netty.bootstrap.ChannelFactory;
|
import io.netty.bootstrap.ChannelFactory;
|
||||||
import io.netty.bootstrap.ServerBootstrap;
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
import io.netty.channel.socket.InternetProtocolFamily;
|
import io.netty.channel.socket.InternetProtocolFamily;
|
||||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||||
@ -100,8 +99,8 @@ class EpollSocketTestPermutation extends SocketTestPermutation {
|
|||||||
public Bootstrap newInstance() {
|
public Bootstrap newInstance() {
|
||||||
return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
|
return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
public Channel newChannel(EventLoop loop) {
|
public Channel newChannel() {
|
||||||
return new NioDatagramChannel(loop, InternetProtocolFamily.IPv4);
|
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,7 +19,6 @@ import gnu.io.CommPort;
|
|||||||
import gnu.io.CommPortIdentifier;
|
import gnu.io.CommPortIdentifier;
|
||||||
import gnu.io.SerialPort;
|
import gnu.io.SerialPort;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.oio.OioByteStreamChannel;
|
import io.netty.channel.oio.OioByteStreamChannel;
|
||||||
|
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
@ -40,8 +39,8 @@ public class RxtxChannel extends OioByteStreamChannel {
|
|||||||
private RxtxDeviceAddress deviceAddress;
|
private RxtxDeviceAddress deviceAddress;
|
||||||
private SerialPort serialPort;
|
private SerialPort serialPort;
|
||||||
|
|
||||||
public RxtxChannel(EventLoop eventLoop) {
|
public RxtxChannel() {
|
||||||
super(null, eventLoop);
|
super(null);
|
||||||
|
|
||||||
config = new DefaultRxtxChannelConfig(this);
|
config = new DefaultRxtxChannelConfig(this);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import io.netty.channel.ChannelFuture;
|
|||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.RecvByteBufAllocator;
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||||
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
||||||
@ -82,15 +81,15 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett
|
|||||||
/**
|
/**
|
||||||
* Create a new instance
|
* Create a new instance
|
||||||
*/
|
*/
|
||||||
public NioSctpChannel(EventLoop eventLoop) {
|
public NioSctpChannel() {
|
||||||
this(eventLoop, newSctpChannel());
|
this(newSctpChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance using {@link SctpChannel}
|
* Create a new instance using {@link SctpChannel}
|
||||||
*/
|
*/
|
||||||
public NioSctpChannel(EventLoop eventLoop, SctpChannel sctpChannel) {
|
public NioSctpChannel(SctpChannel sctpChannel) {
|
||||||
this(null, eventLoop, sctpChannel);
|
this(null, sctpChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,8 +99,8 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett
|
|||||||
* or {@code null}.
|
* or {@code null}.
|
||||||
* @param sctpChannel the underlying {@link SctpChannel}
|
* @param sctpChannel the underlying {@link SctpChannel}
|
||||||
*/
|
*/
|
||||||
public NioSctpChannel(Channel parent, EventLoop eventLoop, SctpChannel sctpChannel) {
|
public NioSctpChannel(Channel parent, SctpChannel sctpChannel) {
|
||||||
super(parent, eventLoop, sctpChannel, SelectionKey.OP_READ);
|
super(parent, sctpChannel, SelectionKey.OP_READ);
|
||||||
try {
|
try {
|
||||||
sctpChannel.configureBlocking(false);
|
sctpChannel.configureBlocking(false);
|
||||||
config = new NioSctpChannelConfig(this, sctpChannel);
|
config = new NioSctpChannelConfig(this, sctpChannel);
|
||||||
|
@ -22,9 +22,7 @@ import io.netty.channel.ChannelFuture;
|
|||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.nio.AbstractNioMessageServerChannel;
|
|
||||||
import io.netty.channel.sctp.DefaultSctpServerChannelConfig;
|
import io.netty.channel.sctp.DefaultSctpServerChannelConfig;
|
||||||
import io.netty.channel.sctp.SctpServerChannelConfig;
|
import io.netty.channel.sctp.SctpServerChannelConfig;
|
||||||
|
|
||||||
@ -46,9 +44,8 @@ import java.util.Set;
|
|||||||
* Be aware that not all operations systems support SCTP. Please refer to the documentation of your operation system,
|
* Be aware that not all operations systems support SCTP. Please refer to the documentation of your operation system,
|
||||||
* to understand what you need to do to use it. Also this feature is only supported on Java 7+.
|
* to understand what you need to do to use it. Also this feature is only supported on Java 7+.
|
||||||
*/
|
*/
|
||||||
public class NioSctpServerChannel extends AbstractNioMessageServerChannel
|
public class NioSctpServerChannel extends AbstractNioMessageChannel
|
||||||
implements io.netty.channel.sctp.SctpServerChannel {
|
implements io.netty.channel.sctp.SctpServerChannel {
|
||||||
|
|
||||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||||
|
|
||||||
private static SctpServerChannel newSocket() {
|
private static SctpServerChannel newSocket() {
|
||||||
@ -65,9 +62,9 @@ public class NioSctpServerChannel extends AbstractNioMessageServerChannel
|
|||||||
/**
|
/**
|
||||||
* Create a new instance
|
* Create a new instance
|
||||||
*/
|
*/
|
||||||
public NioSctpServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
public NioSctpServerChannel() {
|
||||||
super(null, eventLoop, childGroup, newSocket(), SelectionKey.OP_ACCEPT);
|
super(null, newSocket(), SelectionKey.OP_ACCEPT);
|
||||||
config = new NioSctpServerChannelConfig(this, javaChannel());
|
config = new DefaultSctpServerChannelConfig(this, javaChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -143,7 +140,7 @@ public class NioSctpServerChannel extends AbstractNioMessageServerChannel
|
|||||||
if (ch == null) {
|
if (ch == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
buf.add(new NioSctpChannel(this, childEventLoopGroup().next(), ch));
|
buf.add(new NioSctpChannel(this, ch));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import io.netty.channel.ChannelFuture;
|
|||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.RecvByteBufAllocator;
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||||
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
||||||
@ -88,8 +87,8 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
|||||||
/**
|
/**
|
||||||
* Create a new instance with an new {@link SctpChannel}.
|
* Create a new instance with an new {@link SctpChannel}.
|
||||||
*/
|
*/
|
||||||
public OioSctpChannel(EventLoop eventLoop) {
|
public OioSctpChannel() {
|
||||||
this(eventLoop, openChannel());
|
this(openChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,8 +96,8 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
|||||||
*
|
*
|
||||||
* @param ch the {@link SctpChannel} which is used by this instance
|
* @param ch the {@link SctpChannel} which is used by this instance
|
||||||
*/
|
*/
|
||||||
public OioSctpChannel(EventLoop eventLoop, SctpChannel ch) {
|
public OioSctpChannel(SctpChannel ch) {
|
||||||
this(null, eventLoop, ch);
|
this(null, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,8 +107,8 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
|||||||
* {@link} has no parent as it was created by your self.
|
* {@link} has no parent as it was created by your self.
|
||||||
* @param ch the {@link SctpChannel} which is used by this instance
|
* @param ch the {@link SctpChannel} which is used by this instance
|
||||||
*/
|
*/
|
||||||
public OioSctpChannel(Channel parent, EventLoop eventLoop, SctpChannel ch) {
|
public OioSctpChannel(Channel parent, SctpChannel ch) {
|
||||||
super(parent, eventLoop);
|
super(parent);
|
||||||
this.ch = ch;
|
this.ch = ch;
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
|
@ -22,9 +22,7 @@ import io.netty.channel.ChannelFuture;
|
|||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.oio.AbstractOioMessageServerChannel;
|
|
||||||
import io.netty.channel.sctp.DefaultSctpServerChannelConfig;
|
import io.netty.channel.sctp.DefaultSctpServerChannelConfig;
|
||||||
import io.netty.channel.sctp.SctpServerChannelConfig;
|
import io.netty.channel.sctp.SctpServerChannelConfig;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
@ -49,7 +47,7 @@ import java.util.Set;
|
|||||||
* Be aware that not all operations systems support SCTP. Please refer to the documentation of your operation system,
|
* Be aware that not all operations systems support SCTP. Please refer to the documentation of your operation system,
|
||||||
* to understand what you need to do to use it. Also this feature is only supported on Java 7+.
|
* to understand what you need to do to use it. Also this feature is only supported on Java 7+.
|
||||||
*/
|
*/
|
||||||
public class OioSctpServerChannel extends AbstractOioMessageServerChannel
|
public class OioSctpServerChannel extends AbstractOioMessageChannel
|
||||||
implements io.netty.channel.sctp.SctpServerChannel {
|
implements io.netty.channel.sctp.SctpServerChannel {
|
||||||
|
|
||||||
private static final InternalLogger logger =
|
private static final InternalLogger logger =
|
||||||
@ -72,8 +70,8 @@ public class OioSctpServerChannel extends AbstractOioMessageServerChannel
|
|||||||
/**
|
/**
|
||||||
* Create a new instance with an new {@link SctpServerChannel}
|
* Create a new instance with an new {@link SctpServerChannel}
|
||||||
*/
|
*/
|
||||||
public OioSctpServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
public OioSctpServerChannel() {
|
||||||
this(eventLoop, childGroup, newServerSocket());
|
this(newServerSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,8 +79,8 @@ public class OioSctpServerChannel extends AbstractOioMessageServerChannel
|
|||||||
*
|
*
|
||||||
* @param sch the {@link SctpServerChannel} which is used by this instance
|
* @param sch the {@link SctpServerChannel} which is used by this instance
|
||||||
*/
|
*/
|
||||||
public OioSctpServerChannel(EventLoop eventLoop, EventLoopGroup childGroup, SctpServerChannel sch) {
|
public OioSctpServerChannel(SctpServerChannel sch) {
|
||||||
super(null, eventLoop, childGroup);
|
super(null);
|
||||||
if (sch == null) {
|
if (sch == null) {
|
||||||
throw new NullPointerException("sctp server channel");
|
throw new NullPointerException("sctp server channel");
|
||||||
}
|
}
|
||||||
@ -198,7 +196,7 @@ public class OioSctpServerChannel extends AbstractOioMessageServerChannel
|
|||||||
if (key.isAcceptable()) {
|
if (key.isAcceptable()) {
|
||||||
s = sch.accept();
|
s = sch.accept();
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
buf.add(new OioSctpChannel(this, childEventLoopGroup().next(), s));
|
buf.add(new OioSctpChannel(this, s));
|
||||||
acceptedChannels ++;
|
acceptedChannels ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,7 @@ import com.barchart.udt.TypeUDT;
|
|||||||
import com.barchart.udt.nio.ServerSocketChannelUDT;
|
import com.barchart.udt.nio.ServerSocketChannelUDT;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.nio.AbstractNioMessageServerChannel;
|
|
||||||
import io.netty.channel.udt.DefaultUdtServerChannelConfig;
|
import io.netty.channel.udt.DefaultUdtServerChannelConfig;
|
||||||
import io.netty.channel.udt.UdtServerChannel;
|
import io.netty.channel.udt.UdtServerChannel;
|
||||||
import io.netty.channel.udt.UdtServerChannelConfig;
|
import io.netty.channel.udt.UdtServerChannelConfig;
|
||||||
@ -36,16 +34,15 @@ import static java.nio.channels.SelectionKey.*;
|
|||||||
/**
|
/**
|
||||||
* Common base for Netty Byte/Message UDT Stream/Datagram acceptors.
|
* Common base for Netty Byte/Message UDT Stream/Datagram acceptors.
|
||||||
*/
|
*/
|
||||||
public abstract class NioUdtAcceptorChannel extends AbstractNioMessageServerChannel implements UdtServerChannel {
|
public abstract class NioUdtAcceptorChannel extends AbstractNioMessageChannel implements UdtServerChannel {
|
||||||
|
|
||||||
protected static final InternalLogger logger =
|
protected static final InternalLogger logger =
|
||||||
InternalLoggerFactory.getInstance(NioUdtAcceptorChannel.class);
|
InternalLoggerFactory.getInstance(NioUdtAcceptorChannel.class);
|
||||||
|
|
||||||
private final UdtServerChannelConfig config;
|
private final UdtServerChannelConfig config;
|
||||||
|
|
||||||
protected NioUdtAcceptorChannel(EventLoop eventLoop, EventLoopGroup childGroup,
|
protected NioUdtAcceptorChannel(final ServerSocketChannelUDT channelUDT) {
|
||||||
ServerSocketChannelUDT channelUDT) {
|
super(null, channelUDT, OP_ACCEPT);
|
||||||
super(null, eventLoop, childGroup, channelUDT, OP_ACCEPT);
|
|
||||||
try {
|
try {
|
||||||
channelUDT.configureBlocking(false);
|
channelUDT.configureBlocking(false);
|
||||||
config = new DefaultUdtServerChannelConfig(this, channelUDT, true);
|
config = new DefaultUdtServerChannelConfig(this, channelUDT, true);
|
||||||
@ -61,8 +58,8 @@ public abstract class NioUdtAcceptorChannel extends AbstractNioMessageServerChan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected NioUdtAcceptorChannel(EventLoop eventLoop, EventLoopGroup childGroup, final TypeUDT type) {
|
protected NioUdtAcceptorChannel(final TypeUDT type) {
|
||||||
this(eventLoop, childGroup, NioUdtProvider.newAcceptorChannelUDT(type));
|
this(NioUdtProvider.newAcceptorChannelUDT(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,8 +18,6 @@ package io.netty.channel.udt.nio;
|
|||||||
import com.barchart.udt.TypeUDT;
|
import com.barchart.udt.TypeUDT;
|
||||||
import com.barchart.udt.nio.SocketChannelUDT;
|
import com.barchart.udt.nio.SocketChannelUDT;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -30,8 +28,8 @@ public class NioUdtByteAcceptorChannel extends NioUdtAcceptorChannel {
|
|||||||
|
|
||||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||||
|
|
||||||
public NioUdtByteAcceptorChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
public NioUdtByteAcceptorChannel() {
|
||||||
super(eventLoop, childGroup, TypeUDT.STREAM);
|
super(TypeUDT.STREAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -40,7 +38,7 @@ public class NioUdtByteAcceptorChannel extends NioUdtAcceptorChannel {
|
|||||||
if (channelUDT == null) {
|
if (channelUDT == null) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
buf.add(new NioUdtByteConnectorChannel(this, childEventLoopGroup().next(), channelUDT));
|
buf.add(new NioUdtByteConnectorChannel(this, channelUDT));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.FileRegion;
|
import io.netty.channel.FileRegion;
|
||||||
import io.netty.channel.nio.AbstractNioByteChannel;
|
import io.netty.channel.nio.AbstractNioByteChannel;
|
||||||
import io.netty.channel.udt.DefaultUdtChannelConfig;
|
import io.netty.channel.udt.DefaultUdtChannelConfig;
|
||||||
@ -47,12 +46,12 @@ public class NioUdtByteConnectorChannel extends AbstractNioByteChannel implement
|
|||||||
|
|
||||||
private final UdtChannelConfig config;
|
private final UdtChannelConfig config;
|
||||||
|
|
||||||
public NioUdtByteConnectorChannel(EventLoop eventLoop) {
|
public NioUdtByteConnectorChannel() {
|
||||||
this(eventLoop, TypeUDT.STREAM);
|
this(TypeUDT.STREAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NioUdtByteConnectorChannel(Channel parent, EventLoop eventLoop, SocketChannelUDT channelUDT) {
|
public NioUdtByteConnectorChannel(final Channel parent, final SocketChannelUDT channelUDT) {
|
||||||
super(parent, eventLoop, channelUDT);
|
super(parent, channelUDT);
|
||||||
try {
|
try {
|
||||||
channelUDT.configureBlocking(false);
|
channelUDT.configureBlocking(false);
|
||||||
switch (channelUDT.socketUDT().status()) {
|
switch (channelUDT.socketUDT().status()) {
|
||||||
@ -76,12 +75,12 @@ public class NioUdtByteConnectorChannel extends AbstractNioByteChannel implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public NioUdtByteConnectorChannel(EventLoop eventLoop, final SocketChannelUDT channelUDT) {
|
public NioUdtByteConnectorChannel(final SocketChannelUDT channelUDT) {
|
||||||
this(null, eventLoop, channelUDT);
|
this(null, channelUDT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NioUdtByteConnectorChannel(EventLoop eventLoop, final TypeUDT type) {
|
public NioUdtByteConnectorChannel(final TypeUDT type) {
|
||||||
this(eventLoop, NioUdtProvider.newConnectorChannelUDT(type));
|
this(NioUdtProvider.newConnectorChannelUDT(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,17 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.channel.udt.nio;
|
package io.netty.channel.udt.nio;
|
||||||
|
|
||||||
|
|
||||||
import com.barchart.udt.TypeUDT;
|
import com.barchart.udt.TypeUDT;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Byte Channel Rendezvous for UDT Streams.
|
* Byte Channel Rendezvous for UDT Streams.
|
||||||
*/
|
*/
|
||||||
public class NioUdtByteRendezvousChannel extends NioUdtByteConnectorChannel {
|
public class NioUdtByteRendezvousChannel extends NioUdtByteConnectorChannel {
|
||||||
|
|
||||||
public NioUdtByteRendezvousChannel(EventLoop eventLoop) {
|
public NioUdtByteRendezvousChannel() {
|
||||||
super(eventLoop, NioUdtProvider.newRendezvousChannelUDT(TypeUDT.STREAM));
|
super(NioUdtProvider.newRendezvousChannelUDT(TypeUDT.STREAM));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,6 @@ package io.netty.channel.udt.nio;
|
|||||||
import com.barchart.udt.TypeUDT;
|
import com.barchart.udt.TypeUDT;
|
||||||
import com.barchart.udt.nio.SocketChannelUDT;
|
import com.barchart.udt.nio.SocketChannelUDT;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -30,8 +28,8 @@ public class NioUdtMessageAcceptorChannel extends NioUdtAcceptorChannel {
|
|||||||
|
|
||||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||||
|
|
||||||
public NioUdtMessageAcceptorChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
public NioUdtMessageAcceptorChannel() {
|
||||||
super(eventLoop, childGroup, TypeUDT.DATAGRAM);
|
super(TypeUDT.DATAGRAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -40,7 +38,7 @@ public class NioUdtMessageAcceptorChannel extends NioUdtAcceptorChannel {
|
|||||||
if (channelUDT == null) {
|
if (channelUDT == null) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
buf.add(new NioUdtMessageConnectorChannel(this, childEventLoopGroup().next(), channelUDT));
|
buf.add(new NioUdtMessageConnectorChannel(this, channelUDT));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import io.netty.channel.Channel;
|
|||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||||
import io.netty.channel.udt.DefaultUdtChannelConfig;
|
import io.netty.channel.udt.DefaultUdtChannelConfig;
|
||||||
import io.netty.channel.udt.UdtChannel;
|
import io.netty.channel.udt.UdtChannel;
|
||||||
@ -51,12 +50,12 @@ public class NioUdtMessageConnectorChannel extends AbstractNioMessageChannel imp
|
|||||||
|
|
||||||
private final UdtChannelConfig config;
|
private final UdtChannelConfig config;
|
||||||
|
|
||||||
public NioUdtMessageConnectorChannel(EventLoop eventLoop) {
|
public NioUdtMessageConnectorChannel() {
|
||||||
this(eventLoop, TypeUDT.DATAGRAM);
|
this(TypeUDT.DATAGRAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NioUdtMessageConnectorChannel(final Channel parent, EventLoop eventLoop, final SocketChannelUDT channelUDT) {
|
public NioUdtMessageConnectorChannel(final Channel parent, final SocketChannelUDT channelUDT) {
|
||||||
super(parent, eventLoop, channelUDT, OP_READ);
|
super(parent, channelUDT, OP_READ);
|
||||||
try {
|
try {
|
||||||
channelUDT.configureBlocking(false);
|
channelUDT.configureBlocking(false);
|
||||||
switch (channelUDT.socketUDT().status()) {
|
switch (channelUDT.socketUDT().status()) {
|
||||||
@ -80,12 +79,12 @@ public class NioUdtMessageConnectorChannel extends AbstractNioMessageChannel imp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public NioUdtMessageConnectorChannel(EventLoop eventLoop, final SocketChannelUDT channelUDT) {
|
public NioUdtMessageConnectorChannel(final SocketChannelUDT channelUDT) {
|
||||||
this(null, eventLoop, channelUDT);
|
this(null, channelUDT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NioUdtMessageConnectorChannel(EventLoop eventLoop, final TypeUDT type) {
|
public NioUdtMessageConnectorChannel(final TypeUDT type) {
|
||||||
this(eventLoop, NioUdtProvider.newConnectorChannelUDT(type));
|
this(NioUdtProvider.newConnectorChannelUDT(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
package io.netty.channel.udt.nio;
|
package io.netty.channel.udt.nio;
|
||||||
|
|
||||||
import com.barchart.udt.TypeUDT;
|
import com.barchart.udt.TypeUDT;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.udt.UdtMessage;
|
import io.netty.channel.udt.UdtMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,9 +23,10 @@ import io.netty.channel.udt.UdtMessage;
|
|||||||
* <p>
|
* <p>
|
||||||
* Note: send/receive must use {@link UdtMessage} in the pipeline
|
* Note: send/receive must use {@link UdtMessage} in the pipeline
|
||||||
*/
|
*/
|
||||||
public class NioUdtMessageRendezvousChannel extends NioUdtMessageConnectorChannel {
|
public class NioUdtMessageRendezvousChannel extends
|
||||||
|
NioUdtMessageConnectorChannel {
|
||||||
|
|
||||||
public NioUdtMessageRendezvousChannel(EventLoop eventLoop) {
|
public NioUdtMessageRendezvousChannel() {
|
||||||
super(eventLoop, NioUdtProvider.newRendezvousChannelUDT(TypeUDT.DATAGRAM));
|
super(NioUdtProvider.newRendezvousChannelUDT(TypeUDT.DATAGRAM));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,10 @@ import com.barchart.udt.nio.SelectorProviderUDT;
|
|||||||
import com.barchart.udt.nio.ServerSocketChannelUDT;
|
import com.barchart.udt.nio.ServerSocketChannelUDT;
|
||||||
import com.barchart.udt.nio.SocketChannelUDT;
|
import com.barchart.udt.nio.SocketChannelUDT;
|
||||||
import io.netty.bootstrap.ChannelFactory;
|
import io.netty.bootstrap.ChannelFactory;
|
||||||
import io.netty.bootstrap.ServerChannelFactory;
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.udt.UdtChannel;
|
|
||||||
import io.netty.channel.udt.UdtServerChannel;
|
import io.netty.channel.udt.UdtServerChannel;
|
||||||
|
import io.netty.channel.udt.UdtChannel;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.channels.spi.SelectorProvider;
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
@ -42,21 +39,21 @@ import java.nio.channels.spi.SelectorProvider;
|
|||||||
* <p>
|
* <p>
|
||||||
* Provides {@link SelectorProvider} for UDT channels.
|
* Provides {@link SelectorProvider} for UDT channels.
|
||||||
*/
|
*/
|
||||||
public abstract class NioUdtProvider {
|
public final class NioUdtProvider<T extends UdtChannel> implements ChannelFactory<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ChannelFactory} for UDT Byte Acceptor. See {@link TypeUDT#STREAM}
|
* {@link ChannelFactory} for UDT Byte Acceptor. See {@link TypeUDT#STREAM}
|
||||||
* and {@link KindUDT#ACCEPTOR}.
|
* and {@link KindUDT#ACCEPTOR}.
|
||||||
*/
|
*/
|
||||||
public static final ServerChannelFactory<UdtServerChannel> BYTE_ACCEPTOR =
|
public static final ChannelFactory<UdtServerChannel> BYTE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(
|
||||||
new NioUdtServerChannelFactory<UdtServerChannel>(TypeUDT.STREAM, KindUDT.ACCEPTOR);
|
TypeUDT.STREAM, KindUDT.ACCEPTOR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ChannelFactory} for UDT Byte Connector. See {@link TypeUDT#STREAM}
|
* {@link ChannelFactory} for UDT Byte Connector. See {@link TypeUDT#STREAM}
|
||||||
* and {@link KindUDT#CONNECTOR}.
|
* and {@link KindUDT#CONNECTOR}.
|
||||||
*/
|
*/
|
||||||
public static final ChannelFactory<UdtChannel> BYTE_CONNECTOR =
|
public static final ChannelFactory<UdtChannel> BYTE_CONNECTOR = new NioUdtProvider<UdtChannel>(
|
||||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.STREAM, KindUDT.CONNECTOR);
|
TypeUDT.STREAM, KindUDT.CONNECTOR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link SelectorProvider} for UDT Byte channels. See
|
* {@link SelectorProvider} for UDT Byte channels. See
|
||||||
@ -68,22 +65,22 @@ public abstract class NioUdtProvider {
|
|||||||
* {@link ChannelFactory} for UDT Byte Rendezvous. See
|
* {@link ChannelFactory} for UDT Byte Rendezvous. See
|
||||||
* {@link TypeUDT#STREAM} and {@link KindUDT#RENDEZVOUS}.
|
* {@link TypeUDT#STREAM} and {@link KindUDT#RENDEZVOUS}.
|
||||||
*/
|
*/
|
||||||
public static final ChannelFactory<UdtChannel> BYTE_RENDEZVOUS =
|
public static final ChannelFactory<UdtChannel> BYTE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(
|
||||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.STREAM, KindUDT.RENDEZVOUS);
|
TypeUDT.STREAM, KindUDT.RENDEZVOUS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ChannelFactory} for UDT Message Acceptor. See
|
* {@link ChannelFactory} for UDT Message Acceptor. See
|
||||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#ACCEPTOR}.
|
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#ACCEPTOR}.
|
||||||
*/
|
*/
|
||||||
public static final ServerChannelFactory<UdtServerChannel> MESSAGE_ACCEPTOR =
|
public static final ChannelFactory<UdtServerChannel> MESSAGE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(
|
||||||
new NioUdtServerChannelFactory<UdtServerChannel>(TypeUDT.DATAGRAM, KindUDT.ACCEPTOR);
|
TypeUDT.DATAGRAM, KindUDT.ACCEPTOR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ChannelFactory} for UDT Message Connector. See
|
* {@link ChannelFactory} for UDT Message Connector. See
|
||||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#CONNECTOR}.
|
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#CONNECTOR}.
|
||||||
*/
|
*/
|
||||||
public static final ChannelFactory<UdtChannel> MESSAGE_CONNECTOR =
|
public static final ChannelFactory<UdtChannel> MESSAGE_CONNECTOR = new NioUdtProvider<UdtChannel>(
|
||||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.DATAGRAM, KindUDT.CONNECTOR);
|
TypeUDT.DATAGRAM, KindUDT.CONNECTOR);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link SelectorProvider} for UDT Message channels. See
|
* {@link SelectorProvider} for UDT Message channels. See
|
||||||
@ -95,8 +92,8 @@ public abstract class NioUdtProvider {
|
|||||||
* {@link ChannelFactory} for UDT Message Rendezvous. See
|
* {@link ChannelFactory} for UDT Message Rendezvous. See
|
||||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#RENDEZVOUS}.
|
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#RENDEZVOUS}.
|
||||||
*/
|
*/
|
||||||
public static final ChannelFactory<UdtChannel> MESSAGE_RENDEZVOUS =
|
public static final ChannelFactory<UdtChannel> MESSAGE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(
|
||||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.DATAGRAM, KindUDT.RENDEZVOUS);
|
TypeUDT.DATAGRAM, KindUDT.RENDEZVOUS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expose underlying {@link ChannelUDT} for debugging and monitoring.
|
* Expose underlying {@link ChannelUDT} for debugging and monitoring.
|
||||||
@ -131,7 +128,8 @@ public abstract class NioUdtProvider {
|
|||||||
/**
|
/**
|
||||||
* Convenience factory for {@link KindUDT#ACCEPTOR} channels.
|
* Convenience factory for {@link KindUDT#ACCEPTOR} channels.
|
||||||
*/
|
*/
|
||||||
protected static ServerSocketChannelUDT newAcceptorChannelUDT(final TypeUDT type) {
|
protected static ServerSocketChannelUDT newAcceptorChannelUDT(
|
||||||
|
final TypeUDT type) {
|
||||||
try {
|
try {
|
||||||
return SelectorProviderUDT.from(type).openServerSocketChannel();
|
return SelectorProviderUDT.from(type).openServerSocketChannel();
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
@ -153,7 +151,8 @@ public abstract class NioUdtProvider {
|
|||||||
/**
|
/**
|
||||||
* Convenience factory for {@link KindUDT#RENDEZVOUS} channels.
|
* Convenience factory for {@link KindUDT#RENDEZVOUS} channels.
|
||||||
*/
|
*/
|
||||||
protected static RendezvousChannelUDT newRendezvousChannelUDT(final TypeUDT type) {
|
protected static RendezvousChannelUDT newRendezvousChannelUDT(
|
||||||
|
final TypeUDT type) {
|
||||||
try {
|
try {
|
||||||
return SelectorProviderUDT.from(type).openRendezvousChannel();
|
return SelectorProviderUDT.from(type).openRendezvousChannel();
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
@ -195,70 +194,42 @@ public abstract class NioUdtProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produce new {@link UdtChannel} based on factory {@link #kind()} and {@link #type()}
|
* Produce new {@link UdtChannel} based on factory {@link #kind()} and
|
||||||
|
* {@link #type()}
|
||||||
*/
|
*/
|
||||||
private static final class NioUdtChannelFactory<T extends UdtChannel>
|
|
||||||
extends NioUdtProvider implements ChannelFactory<T> {
|
|
||||||
|
|
||||||
private NioUdtChannelFactory(final TypeUDT type, final KindUDT kind) {
|
|
||||||
super(type, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public T newChannel(EventLoop eventLoop) {
|
public T newChannel() {
|
||||||
switch (kind()) {
|
switch (kind) {
|
||||||
case ACCEPTOR:
|
case ACCEPTOR:
|
||||||
throw new IllegalStateException("wrong kind: " + kind());
|
switch (type) {
|
||||||
case CONNECTOR:
|
|
||||||
switch (type()) {
|
|
||||||
case DATAGRAM:
|
case DATAGRAM:
|
||||||
return (T) new NioUdtMessageConnectorChannel(eventLoop);
|
return (T) new NioUdtMessageAcceptorChannel();
|
||||||
case STREAM:
|
case STREAM:
|
||||||
return (T) new NioUdtByteConnectorChannel(eventLoop);
|
return (T) new NioUdtByteAcceptorChannel();
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("wrong type: " + type());
|
throw new IllegalStateException("wrong type=" + type);
|
||||||
}
|
|
||||||
case RENDEZVOUS:
|
|
||||||
switch (type()) {
|
|
||||||
case DATAGRAM:
|
|
||||||
return (T) new NioUdtMessageRendezvousChannel(eventLoop);
|
|
||||||
case STREAM:
|
|
||||||
return (T) new NioUdtByteRendezvousChannel(eventLoop);
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("wrong type: " + type());
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("wrong kind: " + kind());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class NioUdtServerChannelFactory<T extends UdtServerChannel> extends NioUdtProvider
|
|
||||||
implements ServerChannelFactory<T> {
|
|
||||||
|
|
||||||
private NioUdtServerChannelFactory(final TypeUDT type, final KindUDT kind) {
|
|
||||||
super(type, kind);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public T newChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
|
||||||
switch (kind()) {
|
|
||||||
case ACCEPTOR:
|
|
||||||
switch (type()) {
|
|
||||||
case DATAGRAM:
|
|
||||||
return (T) new NioUdtMessageAcceptorChannel(eventLoop, childGroup);
|
|
||||||
case STREAM:
|
|
||||||
return (T) new NioUdtByteAcceptorChannel(eventLoop, childGroup);
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("wrong type: " + type());
|
|
||||||
}
|
}
|
||||||
case CONNECTOR:
|
case CONNECTOR:
|
||||||
case RENDEZVOUS:
|
switch (type) {
|
||||||
|
case DATAGRAM:
|
||||||
|
return (T) new NioUdtMessageConnectorChannel();
|
||||||
|
case STREAM:
|
||||||
|
return (T) new NioUdtByteConnectorChannel();
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("wrong kind: " + kind());
|
throw new IllegalStateException("wrong type=" + type);
|
||||||
}
|
}
|
||||||
|
case RENDEZVOUS:
|
||||||
|
switch (type) {
|
||||||
|
case DATAGRAM:
|
||||||
|
return (T) new NioUdtMessageRendezvousChannel();
|
||||||
|
case STREAM:
|
||||||
|
return (T) new NioUdtByteRendezvousChannel();
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("wrong type=" + type);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("wrong kind=" + kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package io.netty.test.udt.nio;
|
package io.netty.test.udt.nio;
|
||||||
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
||||||
import io.netty.channel.udt.nio.NioUdtByteAcceptorChannel;
|
import io.netty.channel.udt.nio.NioUdtByteAcceptorChannel;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -30,7 +28,6 @@ public class NioUdtByteAcceptorChannelTest extends AbstractUdtTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void metadata() throws Exception {
|
public void metadata() throws Exception {
|
||||||
EventLoop loop = new NioEventLoopGroup().next();
|
assertEquals(false, new NioUdtByteAcceptorChannel().metadata().hasDisconnect());
|
||||||
assertFalse(new NioUdtByteAcceptorChannel(loop, new NioEventLoopGroup()).metadata().hasDisconnect());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package io.netty.test.udt.nio;
|
package io.netty.test.udt.nio;
|
||||||
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
||||||
import io.netty.channel.udt.nio.NioUdtByteConnectorChannel;
|
import io.netty.channel.udt.nio.NioUdtByteConnectorChannel;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -30,7 +28,6 @@ public class NioUdtByteConnectorChannelTest extends AbstractUdtTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void metadata() throws Exception {
|
public void metadata() throws Exception {
|
||||||
EventLoop loop = new NioEventLoopGroup().next();
|
assertEquals(false, new NioUdtByteConnectorChannel().metadata().hasDisconnect());
|
||||||
assertFalse(new NioUdtByteConnectorChannel(loop).metadata().hasDisconnect());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import com.yammer.metrics.Metrics;
|
|||||||
import com.yammer.metrics.core.Meter;
|
import com.yammer.metrics.core.Meter;
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.udt.nio.NioUdtByteRendezvousChannel;
|
import io.netty.channel.udt.nio.NioUdtByteRendezvousChannel;
|
||||||
import io.netty.channel.udt.nio.NioUdtProvider;
|
import io.netty.channel.udt.nio.NioUdtProvider;
|
||||||
@ -45,8 +44,7 @@ public class NioUdtByteRendezvousChannelTest extends AbstractUdtTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void metadata() throws Exception {
|
public void metadata() throws Exception {
|
||||||
EventLoop loop = new NioEventLoopGroup().next();
|
assertFalse(new NioUdtByteRendezvousChannel().metadata().hasDisconnect());
|
||||||
assertFalse(new NioUdtByteRendezvousChannel(loop).metadata().hasDisconnect());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package io.netty.test.udt.nio;
|
package io.netty.test.udt.nio;
|
||||||
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
||||||
import io.netty.channel.udt.nio.NioUdtMessageAcceptorChannel;
|
import io.netty.channel.udt.nio.NioUdtMessageAcceptorChannel;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -30,7 +28,6 @@ public class NioUdtMessageAcceptorChannelTest extends AbstractUdtTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void metadata() throws Exception {
|
public void metadata() throws Exception {
|
||||||
EventLoop loop = new NioEventLoopGroup().next();
|
assertEquals(false, new NioUdtMessageAcceptorChannel().metadata().hasDisconnect());
|
||||||
assertFalse(new NioUdtMessageAcceptorChannel(loop, new NioEventLoopGroup()).metadata().hasDisconnect());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package io.netty.test.udt.nio;
|
package io.netty.test.udt.nio;
|
||||||
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
||||||
import io.netty.channel.udt.nio.NioUdtMessageConnectorChannel;
|
import io.netty.channel.udt.nio.NioUdtMessageConnectorChannel;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -30,7 +28,6 @@ public class NioUdtMessageConnectorChannelTest extends AbstractUdtTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void metadata() throws Exception {
|
public void metadata() throws Exception {
|
||||||
EventLoop loop = new NioEventLoopGroup().next();
|
assertEquals(false, new NioUdtMessageConnectorChannel().metadata().hasDisconnect());
|
||||||
assertFalse(new NioUdtMessageConnectorChannel(loop).metadata().hasDisconnect());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import com.yammer.metrics.Metrics;
|
|||||||
import com.yammer.metrics.core.Meter;
|
import com.yammer.metrics.core.Meter;
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import io.netty.channel.udt.nio.NioUdtMessageRendezvousChannel;
|
import io.netty.channel.udt.nio.NioUdtMessageRendezvousChannel;
|
||||||
import io.netty.channel.udt.nio.NioUdtProvider;
|
import io.netty.channel.udt.nio.NioUdtProvider;
|
||||||
@ -45,8 +44,7 @@ public class NioUdtMessageRendezvousChannelTest extends AbstractUdtTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void metadata() throws Exception {
|
public void metadata() throws Exception {
|
||||||
EventLoop loop = new NioEventLoopGroup().next();
|
assertFalse(new NioUdtMessageRendezvousChannel().metadata().hasDisconnect());
|
||||||
assertFalse(new NioUdtMessageRendezvousChannel(loop).metadata().hasDisconnect());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
package io.netty.test.udt.nio;
|
package io.netty.test.udt.nio;
|
||||||
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
|
||||||
import io.netty.channel.udt.UdtServerChannel;
|
import io.netty.channel.udt.UdtServerChannel;
|
||||||
import io.netty.channel.udt.nio.NioUdtProvider;
|
import io.netty.channel.udt.nio.NioUdtProvider;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -32,22 +29,18 @@ public class NioUdtProviderTest extends AbstractUdtTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void provideFactory() {
|
public void provideFactory() {
|
||||||
|
|
||||||
EventLoop loop = new NioEventLoopGroup().next();
|
|
||||||
EventLoopGroup childGroup = new NioEventLoopGroup();
|
|
||||||
|
|
||||||
// bytes
|
// bytes
|
||||||
assertNotNull(NioUdtProvider.BYTE_ACCEPTOR.newChannel(loop, childGroup));
|
assertNotNull(NioUdtProvider.BYTE_ACCEPTOR.newChannel());
|
||||||
assertNotNull(NioUdtProvider.BYTE_CONNECTOR.newChannel(loop));
|
assertNotNull(NioUdtProvider.BYTE_CONNECTOR.newChannel());
|
||||||
assertNotNull(NioUdtProvider.BYTE_RENDEZVOUS.newChannel(loop));
|
assertNotNull(NioUdtProvider.BYTE_RENDEZVOUS.newChannel());
|
||||||
|
|
||||||
// message
|
// message
|
||||||
assertNotNull(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel(loop, childGroup));
|
assertNotNull(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel());
|
||||||
assertNotNull(NioUdtProvider.MESSAGE_CONNECTOR.newChannel(loop));
|
assertNotNull(NioUdtProvider.MESSAGE_CONNECTOR.newChannel());
|
||||||
assertNotNull(NioUdtProvider.MESSAGE_RENDEZVOUS.newChannel(loop));
|
assertNotNull(NioUdtProvider.MESSAGE_RENDEZVOUS.newChannel());
|
||||||
|
|
||||||
// acceptor types
|
// acceptor types
|
||||||
assertTrue(NioUdtProvider.BYTE_ACCEPTOR.newChannel(loop, childGroup) instanceof UdtServerChannel);
|
assertTrue(NioUdtProvider.BYTE_ACCEPTOR.newChannel() instanceof UdtServerChannel);
|
||||||
assertTrue(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel(loop, childGroup) instanceof UdtServerChannel);
|
assertTrue(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel() instanceof UdtServerChannel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package io.netty.bootstrap;
|
package io.netty.bootstrap;
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
@ -24,7 +25,6 @@ import io.netty.channel.ChannelOption;
|
|||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.DefaultChannelPromise;
|
import io.netty.channel.DefaultChannelPromise;
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
import io.netty.channel.VoidChannel;
|
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import io.netty.util.concurrent.EventExecutorGroup;
|
import io.netty.util.concurrent.EventExecutorGroup;
|
||||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||||
@ -46,6 +46,7 @@ import java.util.Map;
|
|||||||
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {
|
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {
|
||||||
|
|
||||||
private volatile EventLoopGroup group;
|
private volatile EventLoopGroup group;
|
||||||
|
private volatile ChannelFactory<? extends C> channelFactory;
|
||||||
private volatile SocketAddress localAddress;
|
private volatile SocketAddress localAddress;
|
||||||
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
|
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
|
||||||
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
||||||
@ -57,6 +58,7 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
|
|
||||||
AbstractBootstrap(AbstractBootstrap<B, C> bootstrap) {
|
AbstractBootstrap(AbstractBootstrap<B, C> bootstrap) {
|
||||||
group = bootstrap.group;
|
group = bootstrap.group;
|
||||||
|
channelFactory = bootstrap.channelFactory;
|
||||||
handler = bootstrap.handler;
|
handler = bootstrap.handler;
|
||||||
localAddress = bootstrap.localAddress;
|
localAddress = bootstrap.localAddress;
|
||||||
synchronized (bootstrap.options) {
|
synchronized (bootstrap.options) {
|
||||||
@ -68,7 +70,8 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link EventLoopGroup} which is used to handle all the events for the to-be-created {@link Channel}
|
* The {@link EventLoopGroup} which is used to handle all the events for the to-be-creates
|
||||||
|
* {@link Channel}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public B group(EventLoopGroup group) {
|
public B group(EventLoopGroup group) {
|
||||||
@ -82,6 +85,38 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
return (B) this;
|
return (B) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Class} which is used to create {@link Channel} instances from.
|
||||||
|
* You either use this or {@link #channelFactory(ChannelFactory)} if your
|
||||||
|
* {@link Channel} implementation has no no-args constructor.
|
||||||
|
*/
|
||||||
|
public B channel(Class<? extends C> channelClass) {
|
||||||
|
if (channelClass == null) {
|
||||||
|
throw new NullPointerException("channelClass");
|
||||||
|
}
|
||||||
|
return channelFactory(new BootstrapChannelFactory<C>(channelClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ChannelFactory} which is used to create {@link Channel} instances from
|
||||||
|
* when calling {@link #bind()}. This method is usually only used if {@link #channel(Class)}
|
||||||
|
* is not working for you because of some more complex needs. If your {@link Channel} implementation
|
||||||
|
* has a no-args constructor, its highly recommend to just use {@link #channel(Class)} for
|
||||||
|
* simplify your code.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public B channelFactory(ChannelFactory<? extends C> channelFactory) {
|
||||||
|
if (channelFactory == null) {
|
||||||
|
throw new NullPointerException("channelFactory");
|
||||||
|
}
|
||||||
|
if (this.channelFactory != null) {
|
||||||
|
throw new IllegalStateException("channelFactory set already");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.channelFactory = channelFactory;
|
||||||
|
return (B) this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link SocketAddress} which is used to bind the local "end" to.
|
* The {@link SocketAddress} which is used to bind the local "end" to.
|
||||||
*
|
*
|
||||||
@ -166,6 +201,9 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
if (group == null) {
|
if (group == null) {
|
||||||
throw new IllegalStateException("group not set");
|
throw new IllegalStateException("group not set");
|
||||||
}
|
}
|
||||||
|
if (channelFactory == null) {
|
||||||
|
throw new IllegalStateException("factory not set");
|
||||||
|
}
|
||||||
return (B) this;
|
return (B) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,16 +293,8 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Channel createChannel();
|
|
||||||
|
|
||||||
final ChannelFuture initAndRegister() {
|
final ChannelFuture initAndRegister() {
|
||||||
Channel channel;
|
final Channel channel = channelFactory().newChannel();
|
||||||
try {
|
|
||||||
channel = createChannel();
|
|
||||||
} catch (Throwable t) {
|
|
||||||
return VoidChannel.INSTANCE.newFailedFuture(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
init(channel);
|
init(channel);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@ -272,8 +302,7 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
return channel.newFailedFuture(t);
|
return channel.newFailedFuture(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelPromise regFuture = channel.newPromise();
|
ChannelFuture regFuture = group().register(channel);
|
||||||
channel.unsafe().register(regFuture);
|
|
||||||
if (regFuture.cause() != null) {
|
if (regFuture.cause() != null) {
|
||||||
if (channel.isRegistered()) {
|
if (channel.isRegistered()) {
|
||||||
channel.close();
|
channel.close();
|
||||||
@ -330,6 +359,10 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
return localAddress;
|
return localAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final ChannelFactory<? extends C> channelFactory() {
|
||||||
|
return channelFactory;
|
||||||
|
}
|
||||||
|
|
||||||
final ChannelHandler handler() {
|
final ChannelHandler handler() {
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
@ -359,6 +392,11 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
buf.append(StringUtil.simpleClassName(group));
|
buf.append(StringUtil.simpleClassName(group));
|
||||||
buf.append(", ");
|
buf.append(", ");
|
||||||
}
|
}
|
||||||
|
if (channelFactory != null) {
|
||||||
|
buf.append("channelFactory: ");
|
||||||
|
buf.append(channelFactory);
|
||||||
|
buf.append(", ");
|
||||||
|
}
|
||||||
if (localAddress != null) {
|
if (localAddress != null) {
|
||||||
buf.append("localAddress: ");
|
buf.append("localAddress: ");
|
||||||
buf.append(localAddress);
|
buf.append(localAddress);
|
||||||
@ -391,4 +429,26 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
|||||||
}
|
}
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class BootstrapChannelFactory<T extends Channel> implements ChannelFactory<T> {
|
||||||
|
private final Class<? extends T> clazz;
|
||||||
|
|
||||||
|
BootstrapChannelFactory(Class<? extends T> clazz) {
|
||||||
|
this.clazz = clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T newChannel() {
|
||||||
|
try {
|
||||||
|
return clazz.newInstance();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new ChannelException("Unable to create Channel from class " + clazz, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return clazz.getSimpleName() + ".class";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,20 +16,15 @@
|
|||||||
package io.netty.bootstrap;
|
package io.netty.bootstrap;
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelException;
|
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.ServerChannel;
|
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import io.netty.util.internal.StringUtil;
|
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
@ -47,58 +42,15 @@ public final class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
|
|||||||
|
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Bootstrap.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Bootstrap.class);
|
||||||
|
|
||||||
private volatile ChannelFactory<? extends Channel> channelFactory;
|
|
||||||
|
|
||||||
private volatile SocketAddress remoteAddress;
|
private volatile SocketAddress remoteAddress;
|
||||||
|
|
||||||
public Bootstrap() { }
|
public Bootstrap() { }
|
||||||
|
|
||||||
private Bootstrap(Bootstrap bootstrap) {
|
private Bootstrap(Bootstrap bootstrap) {
|
||||||
super(bootstrap);
|
super(bootstrap);
|
||||||
channelFactory = bootstrap.channelFactory;
|
|
||||||
remoteAddress = bootstrap.remoteAddress;
|
remoteAddress = bootstrap.remoteAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Class} which is used to create {@link Channel} instances from.
|
|
||||||
* You either use this or {@link #channelFactory(ChannelFactory)} if your
|
|
||||||
* {@link Channel} implementation has no no-args constructor.
|
|
||||||
*/
|
|
||||||
public Bootstrap channel(Class<? extends Channel> channelClass) {
|
|
||||||
if (channelClass == null) {
|
|
||||||
throw new NullPointerException("channelClass");
|
|
||||||
}
|
|
||||||
return channelFactory(new BootstrapChannelFactory<Channel>(channelClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ServerChannelFactory} which is used to create {@link ServerChannel} instances when calling
|
|
||||||
* {@link #bind()}. This method is usually only used if {@link #channel(Class)} is not working for you because of
|
|
||||||
* some more complex needs. If your {@link Channel} implementation has a no-args constructor, its highly recommend
|
|
||||||
* to just use {@link #channel(Class)} for simplify your code.
|
|
||||||
*/
|
|
||||||
public Bootstrap channelFactory(ChannelFactory<? extends Channel> channelFactory) {
|
|
||||||
if (channelFactory == null) {
|
|
||||||
throw new NullPointerException("channelFactory");
|
|
||||||
}
|
|
||||||
if (this.channelFactory != null) {
|
|
||||||
throw new IllegalStateException("channelFactory set already");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.channelFactory = channelFactory;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChannelFactory<? extends Channel> channelFactory() {
|
|
||||||
return channelFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Channel createChannel() {
|
|
||||||
EventLoop eventLoop = group().next();
|
|
||||||
return channelFactory().newChannel(eventLoop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link SocketAddress} to connect to once the {@link #connect()} method
|
* The {@link SocketAddress} to connect to once the {@link #connect()} method
|
||||||
* is called.
|
* is called.
|
||||||
@ -255,9 +207,6 @@ public final class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
|
|||||||
if (handler() == null) {
|
if (handler() == null) {
|
||||||
throw new IllegalStateException("handler not set");
|
throw new IllegalStateException("handler not set");
|
||||||
}
|
}
|
||||||
if (channelFactory == null) {
|
|
||||||
throw new IllegalStateException("channel or channelFactory not set");
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,28 +230,4 @@ public final class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
|
|||||||
|
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class BootstrapChannelFactory<T extends Channel> implements ChannelFactory<T> {
|
|
||||||
|
|
||||||
private final Class<? extends T> clazz;
|
|
||||||
|
|
||||||
BootstrapChannelFactory(Class<? extends T> clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public T newChannel(EventLoop eventLoop) {
|
|
||||||
try {
|
|
||||||
Constructor<? extends T> constructor = clazz.getConstructor(EventLoop.class);
|
|
||||||
return constructor.newInstance(eventLoop);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
throw new ChannelException("Unable to create Channel from class " + clazz, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return StringUtil.simpleClassName(clazz) + ".class";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,16 +16,14 @@
|
|||||||
package io.netty.bootstrap;
|
package io.netty.bootstrap;
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory that creates a new {@link Channel} on {@link Bootstrap#bind()}, {@link Bootstrap#connect()}, and
|
* Factory that creates a new {@link Channel} on {@link Bootstrap#bind()}, {@link Bootstrap#connect()}, and
|
||||||
* {@link ServerBootstrap#bind()}.
|
* {@link ServerBootstrap#bind()}.
|
||||||
*/
|
*/
|
||||||
public interface ChannelFactory<T extends Channel> {
|
public interface ChannelFactory<T extends Channel> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new channel.
|
* Creates a new channel.
|
||||||
*/
|
*/
|
||||||
T newChannel(EventLoop eventLoop);
|
T newChannel();
|
||||||
}
|
}
|
||||||
|
@ -17,24 +17,22 @@ package io.netty.bootstrap;
|
|||||||
|
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelConfig;
|
import io.netty.channel.ChannelConfig;
|
||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerAdapter;
|
import io.netty.channel.ChannelHandlerAdapter;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
import io.netty.channel.EventLoopGroup;
|
||||||
import io.netty.channel.ServerChannel;
|
import io.netty.channel.ServerChannel;
|
||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import io.netty.util.concurrent.EventExecutorGroup;
|
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
@ -48,7 +46,6 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
|
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ServerBootstrap.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ServerBootstrap.class);
|
||||||
|
|
||||||
private volatile ServerChannelFactory<? extends ServerChannel> channelFactory;
|
|
||||||
private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
|
private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
|
||||||
private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
||||||
private volatile EventLoopGroup childGroup;
|
private volatile EventLoopGroup childGroup;
|
||||||
@ -58,7 +55,6 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
|
|
||||||
private ServerBootstrap(ServerBootstrap bootstrap) {
|
private ServerBootstrap(ServerBootstrap bootstrap) {
|
||||||
super(bootstrap);
|
super(bootstrap);
|
||||||
channelFactory = bootstrap.channelFactory;
|
|
||||||
childGroup = bootstrap.childGroup;
|
childGroup = bootstrap.childGroup;
|
||||||
childHandler = bootstrap.childHandler;
|
childHandler = bootstrap.childHandler;
|
||||||
synchronized (bootstrap.childOptions) {
|
synchronized (bootstrap.childOptions) {
|
||||||
@ -69,47 +65,6 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Class} which is used to create {@link Channel} instances from.
|
|
||||||
* You either use this or {@link #channelFactory(ServerChannelFactory)} if your
|
|
||||||
* {@link Channel} implementation has no no-args constructor.
|
|
||||||
*/
|
|
||||||
public ServerBootstrap channel(Class<? extends ServerChannel> channelClass) {
|
|
||||||
if (channelClass == null) {
|
|
||||||
throw new NullPointerException("channelClass");
|
|
||||||
}
|
|
||||||
return channelFactory(new ServerBootstrapChannelFactory<ServerChannel>(channelClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link ChannelFactory} which is used to create {@link Channel} instances from
|
|
||||||
* when calling {@link #bind()}. This method is usually only used if {@link #channel(Class)}
|
|
||||||
* is not working for you because of some more complex needs. If your {@link Channel} implementation
|
|
||||||
* has a no-args constructor, its highly recommend to just use {@link #channel(Class)} for
|
|
||||||
* simplify your code.
|
|
||||||
*/
|
|
||||||
public ServerBootstrap channelFactory(ServerChannelFactory<? extends ServerChannel> channelFactory) {
|
|
||||||
if (channelFactory == null) {
|
|
||||||
throw new NullPointerException("channelFactory");
|
|
||||||
}
|
|
||||||
if (this.channelFactory != null) {
|
|
||||||
throw new IllegalStateException("channelFactory set already");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.channelFactory = channelFactory;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Channel createChannel() {
|
|
||||||
EventLoop eventLoop = group().next();
|
|
||||||
return channelFactory().newChannel(eventLoop, childGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerChannelFactory<? extends ServerChannel> channelFactory() {
|
|
||||||
return channelFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the {@link EventLoopGroup} which is used for the parent (acceptor) and the child (client).
|
* Specify the {@link EventLoopGroup} which is used for the parent (acceptor) and the child (client).
|
||||||
*/
|
*/
|
||||||
@ -119,8 +74,8 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@link EventExecutorGroup} for the parent (acceptor) and the child (client). These
|
* Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These
|
||||||
* {@link EventExecutorGroup}'s are used to handle all the events and IO for {@link SocketChannel} and
|
* {@link EventLoopGroup}'s are used to handle all the events and IO for {@link SocketChannel} and
|
||||||
* {@link Channel}'s.
|
* {@link Channel}'s.
|
||||||
*/
|
*/
|
||||||
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
|
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
|
||||||
@ -212,6 +167,7 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
p.addLast(handler());
|
p.addLast(handler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final EventLoopGroup currentChildGroup = childGroup;
|
||||||
final ChannelHandler currentChildHandler = childHandler;
|
final ChannelHandler currentChildHandler = childHandler;
|
||||||
final Entry<ChannelOption<?>, Object>[] currentChildOptions;
|
final Entry<ChannelOption<?>, Object>[] currentChildOptions;
|
||||||
final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
|
final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
|
||||||
@ -225,8 +181,8 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
p.addLast(new ChannelInitializer<Channel>() {
|
p.addLast(new ChannelInitializer<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
public void initChannel(Channel ch) throws Exception {
|
public void initChannel(Channel ch) throws Exception {
|
||||||
ch.pipeline().addLast(new ServerBootstrapAcceptor(currentChildHandler, currentChildOptions,
|
ch.pipeline().addLast(new ServerBootstrapAcceptor(
|
||||||
currentChildAttrs));
|
currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -241,9 +197,6 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
logger.warn("childGroup is not set. Using parentGroup instead.");
|
logger.warn("childGroup is not set. Using parentGroup instead.");
|
||||||
childGroup = group();
|
childGroup = group();
|
||||||
}
|
}
|
||||||
if (channelFactory == null) {
|
|
||||||
throw new IllegalStateException("channel or channelFactory not set");
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,12 +212,16 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
|
|
||||||
private static class ServerBootstrapAcceptor extends ChannelHandlerAdapter {
|
private static class ServerBootstrapAcceptor extends ChannelHandlerAdapter {
|
||||||
|
|
||||||
|
private final EventLoopGroup childGroup;
|
||||||
private final ChannelHandler childHandler;
|
private final ChannelHandler childHandler;
|
||||||
private final Entry<ChannelOption<?>, Object>[] childOptions;
|
private final Entry<ChannelOption<?>, Object>[] childOptions;
|
||||||
private final Entry<AttributeKey<?>, Object>[] childAttrs;
|
private final Entry<AttributeKey<?>, Object>[] childAttrs;
|
||||||
|
|
||||||
ServerBootstrapAcceptor(ChannelHandler childHandler, Entry<ChannelOption<?>, Object>[] childOptions,
|
@SuppressWarnings("unchecked")
|
||||||
Entry<AttributeKey<?>, Object>[] childAttrs) {
|
ServerBootstrapAcceptor(
|
||||||
|
EventLoopGroup childGroup, ChannelHandler childHandler,
|
||||||
|
Entry<ChannelOption<?>, Object>[] childOptions, Entry<AttributeKey<?>, Object>[] childAttrs) {
|
||||||
|
this.childGroup = childGroup;
|
||||||
this.childHandler = childHandler;
|
this.childHandler = childHandler;
|
||||||
this.childOptions = childOptions;
|
this.childOptions = childOptions;
|
||||||
this.childAttrs = childAttrs;
|
this.childAttrs = childAttrs;
|
||||||
@ -273,7 +230,7 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||||
Channel child = (Channel) msg;
|
final Channel child = (Channel) msg;
|
||||||
|
|
||||||
child.pipeline().addLast(childHandler);
|
child.pipeline().addLast(childHandler);
|
||||||
|
|
||||||
@ -291,7 +248,23 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
|
child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
child.unsafe().register(child.newPromise());
|
try {
|
||||||
|
childGroup.register(child).addListener(new ChannelFutureListener() {
|
||||||
|
@Override
|
||||||
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
|
if (!future.isSuccess()) {
|
||||||
|
forceClose(child, future.cause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Throwable t) {
|
||||||
|
forceClose(child, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void forceClose(Channel child, Throwable t) {
|
||||||
|
child.unsafe().closeForcibly();
|
||||||
|
logger.warn("Failed to register an accepted channel: " + child, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -358,29 +331,5 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
|||||||
|
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ServerBootstrapChannelFactory<T extends ServerChannel>
|
|
||||||
implements ServerChannelFactory<T> {
|
|
||||||
|
|
||||||
private final Class<? extends T> clazz;
|
|
||||||
|
|
||||||
ServerBootstrapChannelFactory(Class<? extends T> clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public T newChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
|
||||||
try {
|
|
||||||
Constructor<? extends T> constructor = clazz.getConstructor(EventLoop.class, EventLoopGroup.class);
|
|
||||||
return constructor.newInstance(eventLoop, childGroup);
|
|
||||||
} catch (Throwable t) {
|
|
||||||
throw new ChannelException("Unable to create Channel from class " + clazz, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return StringUtil.simpleClassName(clazz) + ".class";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 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 io.netty.bootstrap;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.ServerChannel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Factory that creates a new {@link Channel} on {@link Bootstrap#bind()}, {@link Bootstrap#connect()}, and
|
|
||||||
* {@link ServerBootstrap#bind()}.
|
|
||||||
*/
|
|
||||||
public interface ServerChannelFactory<T extends ServerChannel> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new channel.
|
|
||||||
*/
|
|
||||||
T newChannel(EventLoop eventLoop, EventLoopGroup childGroup);
|
|
||||||
}
|
|
@ -59,7 +59,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
|
|
||||||
private volatile SocketAddress localAddress;
|
private volatile SocketAddress localAddress;
|
||||||
private volatile SocketAddress remoteAddress;
|
private volatile SocketAddress remoteAddress;
|
||||||
private final EventLoop eventLoop;
|
private volatile EventLoop eventLoop;
|
||||||
private volatile boolean registered;
|
private volatile boolean registered;
|
||||||
|
|
||||||
/** Cache for the string representation of this channel */
|
/** Cache for the string representation of this channel */
|
||||||
@ -72,9 +72,8 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
* @param parent
|
* @param parent
|
||||||
* the parent of this channel. {@code null} if there's no parent.
|
* the parent of this channel. {@code null} if there's no parent.
|
||||||
*/
|
*/
|
||||||
protected AbstractChannel(Channel parent, EventLoop eventLoop) {
|
protected AbstractChannel(Channel parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.eventLoop = validate(eventLoop);
|
|
||||||
unsafe = newUnsafe();
|
unsafe = newUnsafe();
|
||||||
pipeline = new DefaultChannelPipeline(this);
|
pipeline = new DefaultChannelPipeline(this);
|
||||||
}
|
}
|
||||||
@ -107,6 +106,10 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventLoop eventLoop() {
|
public EventLoop eventLoop() {
|
||||||
|
EventLoop eventLoop = this.eventLoop;
|
||||||
|
if (eventLoop == null) {
|
||||||
|
throw new IllegalStateException("channel not registered to an event loop");
|
||||||
|
}
|
||||||
return eventLoop;
|
return eventLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +182,11 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
return pipeline.close();
|
return pipeline.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture deregister() {
|
||||||
|
return pipeline.deregister();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Channel flush() {
|
public Channel flush() {
|
||||||
pipeline.flush();
|
pipeline.flush();
|
||||||
@ -210,6 +218,11 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
return pipeline.close(promise);
|
return pipeline.close(promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture deregister(ChannelPromise promise) {
|
||||||
|
return pipeline.deregister(promise);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Channel read() {
|
public Channel read() {
|
||||||
pipeline.read();
|
pipeline.read();
|
||||||
@ -375,7 +388,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ChannelHandlerInvoker invoker() {
|
public final ChannelHandlerInvoker invoker() {
|
||||||
return eventLoop.asInvoker();
|
return eventLoop().asInvoker();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -394,7 +407,22 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void register(final ChannelPromise promise) {
|
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
|
||||||
|
if (eventLoop == null) {
|
||||||
|
throw new NullPointerException("eventLoop");
|
||||||
|
}
|
||||||
|
if (isRegistered()) {
|
||||||
|
promise.setFailure(new IllegalStateException("registered to an event loop already"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isCompatible(eventLoop)) {
|
||||||
|
promise.setFailure(new IllegalStateException("incompatible event loop type: " +
|
||||||
|
eventLoop.getClass().getName()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractChannel.this.eventLoop = eventLoop;
|
||||||
|
|
||||||
if (eventLoop.inEventLoop()) {
|
if (eventLoop.inEventLoop()) {
|
||||||
register0(promise);
|
register0(promise);
|
||||||
} else {
|
} else {
|
||||||
@ -552,7 +580,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deregister();
|
deregister(voidPromise());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,8 +593,14 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deregister() {
|
@Override
|
||||||
|
public final void deregister(final ChannelPromise promise) {
|
||||||
|
if (!promise.setUncancellable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!registered) {
|
if (!registered) {
|
||||||
|
safeSetSuccess(promise);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,6 +611,18 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
} finally {
|
} finally {
|
||||||
if (registered) {
|
if (registered) {
|
||||||
registered = false;
|
registered = false;
|
||||||
|
invokeLater(new OneTimeTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
pipeline.fireChannelUnregistered();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
safeSetSuccess(promise);
|
||||||
|
} else {
|
||||||
|
// Some transports like local and AIO does not allow the deregistration of
|
||||||
|
// an open channel. Their doDeregister() calls close(). Consequently,
|
||||||
|
// close() calls deregister() again - no need to fire channelUnregistered.
|
||||||
|
safeSetSuccess(promise);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -718,16 +764,6 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private EventLoop validate(EventLoop eventLoop) {
|
|
||||||
if (eventLoop == null) {
|
|
||||||
throw new IllegalStateException("null event loop");
|
|
||||||
}
|
|
||||||
if (!isCompatible(eventLoop)) {
|
|
||||||
throw new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName());
|
|
||||||
}
|
|
||||||
return eventLoop;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link ChannelOutboundBuffer} which holds the pending messages for this {@link AbstractChannel}.
|
* Create a new {@link ChannelOutboundBuffer} which holds the pending messages for this {@link AbstractChannel}.
|
||||||
*/
|
*/
|
||||||
|
@ -34,14 +34,11 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
|
|||||||
|
|
||||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||||
|
|
||||||
private final EventLoopGroup childGroup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
*/
|
*/
|
||||||
protected AbstractServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
protected AbstractServerChannel() {
|
||||||
super(null, eventLoop);
|
super(null);
|
||||||
this.childGroup = childGroup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -74,11 +71,6 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public EventLoopGroup childEventLoopGroup() {
|
|
||||||
return childGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class DefaultServerUnsafe extends AbstractUnsafe {
|
private final class DefaultServerUnsafe extends AbstractUnsafe {
|
||||||
@Override
|
@Override
|
||||||
public void write(Object msg, ChannelPromise promise) {
|
public void write(Object msg, ChannelPromise promise) {
|
||||||
|
@ -280,6 +280,19 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
|||||||
*/
|
*/
|
||||||
ChannelFuture close();
|
ChannelFuture close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to deregister this {@link Channel} from the previous assigned {@link EventLoop} and notify the
|
||||||
|
* {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
|
||||||
|
* an error.
|
||||||
|
* <p>
|
||||||
|
* This will result in having the
|
||||||
|
* {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
|
||||||
|
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ChannelFuture deregister();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
|
* Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
|
||||||
* completes, either because the operation was successful or because of an error.
|
* completes, either because the operation was successful or because of an error.
|
||||||
@ -353,6 +366,20 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
|||||||
*/
|
*/
|
||||||
ChannelFuture close(ChannelPromise promise);
|
ChannelFuture close(ChannelPromise promise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to deregister this {@link Channel} from the previous assigned {@link EventLoop} and notify the
|
||||||
|
* {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
|
||||||
|
* an error.
|
||||||
|
*
|
||||||
|
* The given {@link ChannelPromise} will be notified.
|
||||||
|
* <p>
|
||||||
|
* This will result in having the
|
||||||
|
* {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
|
||||||
|
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*/
|
||||||
|
ChannelFuture deregister(ChannelPromise promise);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
|
* Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
|
||||||
* {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
|
* {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
|
||||||
@ -406,6 +433,7 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
|||||||
* <li>{@link #remoteAddress()}</li>
|
* <li>{@link #remoteAddress()}</li>
|
||||||
* <li>{@link #closeForcibly()}</li>
|
* <li>{@link #closeForcibly()}</li>
|
||||||
* <li>{@link #register(ChannelPromise)}</li>
|
* <li>{@link #register(ChannelPromise)}</li>
|
||||||
|
* <li>{@link #deregister(ChannelPromise)}</li>
|
||||||
* <li>{@link #voidPromise()}</li>
|
* <li>{@link #voidPromise()}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@ -432,7 +460,7 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
|||||||
* Register the {@link Channel} of the {@link ChannelPromise} and notify
|
* Register the {@link Channel} of the {@link ChannelPromise} and notify
|
||||||
* the {@link ChannelFuture} once the registration was complete.
|
* the {@link ChannelFuture} once the registration was complete.
|
||||||
*/
|
*/
|
||||||
void register(ChannelPromise promise);
|
void register(EventLoop eventLoop, ChannelPromise promise);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind the {@link SocketAddress} to the {@link Channel} of the {@link ChannelPromise} and notify
|
* Bind the {@link SocketAddress} to the {@link Channel} of the {@link ChannelPromise} and notify
|
||||||
@ -467,6 +495,12 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
|||||||
*/
|
*/
|
||||||
void closeForcibly();
|
void closeForcibly();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deregister the {@link Channel} of the {@link ChannelPromise} from {@link EventLoop} and notify the
|
||||||
|
* {@link ChannelPromise} once the operation was complete.
|
||||||
|
*/
|
||||||
|
void deregister(ChannelPromise promise);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a read operation that fills the inbound buffer of the first {@link ChannelHandler} in the
|
* Schedules a read operation that fills the inbound buffer of the first {@link ChannelHandler} in the
|
||||||
* {@link ChannelPipeline}. If there's already a pending read operation, this method does nothing.
|
* {@link ChannelPipeline}. If there's already a pending read operation, this method does nothing.
|
||||||
|
@ -196,6 +196,11 @@ public interface ChannelHandler {
|
|||||||
*/
|
*/
|
||||||
void channelRegistered(ChannelHandlerContext ctx) throws Exception;
|
void channelRegistered(ChannelHandlerContext ctx) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Channel} of the {@link ChannelHandlerContext} was unregistered from its {@link EventLoop}
|
||||||
|
*/
|
||||||
|
void channelUnregistered(ChannelHandlerContext ctx) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Channel} of the {@link ChannelHandlerContext} is now active
|
* The {@link Channel} of the {@link ChannelHandlerContext} is now active
|
||||||
*/
|
*/
|
||||||
@ -276,6 +281,15 @@ public interface ChannelHandler {
|
|||||||
*/
|
*/
|
||||||
void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
|
void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once a deregister operation is made from the current registered {@link EventLoop}.
|
||||||
|
*
|
||||||
|
* @param ctx the {@link ChannelHandlerContext} for which the close operation is made
|
||||||
|
* @param promise the {@link ChannelPromise} to notify once the operation completes
|
||||||
|
* @throws Exception thrown if an error accour
|
||||||
|
*/
|
||||||
|
void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercepts {@link ChannelHandlerContext#read()}.
|
* Intercepts {@link ChannelHandlerContext#read()}.
|
||||||
*/
|
*/
|
||||||
|
@ -102,6 +102,18 @@ public class ChannelHandlerAdapter implements ChannelHandler {
|
|||||||
ctx.fireChannelRegistered();
|
ctx.fireChannelRegistered();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link ChannelHandlerContext#fireChannelRegistered()} to forward
|
||||||
|
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
||||||
|
*
|
||||||
|
* Sub-classes may override this method to change behavior.
|
||||||
|
*/
|
||||||
|
@Skip
|
||||||
|
@Override
|
||||||
|
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
ctx.fireChannelUnregistered();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls {@link ChannelHandlerContext#fireChannelActive()} to forward
|
* Calls {@link ChannelHandlerContext#fireChannelActive()} to forward
|
||||||
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
||||||
@ -224,6 +236,18 @@ public class ChannelHandlerAdapter implements ChannelHandler {
|
|||||||
ctx.close(promise);
|
ctx.close(promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls {@link ChannelHandlerContext#deregister(ChannelPromise)} to forward
|
||||||
|
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
||||||
|
*
|
||||||
|
* Sub-classes may override this method to change behavior.
|
||||||
|
*/
|
||||||
|
@Skip
|
||||||
|
@Override
|
||||||
|
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
|
||||||
|
ctx.deregister(promise);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls {@link ChannelHandlerContext#read()} to forward
|
* Calls {@link ChannelHandlerContext#read()} to forward
|
||||||
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
||||||
|
@ -192,7 +192,10 @@ public class ChannelHandlerAppender extends ChannelHandlerAdapter {
|
|||||||
} else {
|
} else {
|
||||||
name = e.name;
|
name = e.name;
|
||||||
}
|
}
|
||||||
pipeline.addAfter(ctx.invoker(), oldName, name, e.handler);
|
// Pass in direct the invoker to eliminate the possibility of an IllegalStateException
|
||||||
|
// if the Channel is not registered yet.
|
||||||
|
DefaultChannelHandlerContext context = (DefaultChannelHandlerContext) ctx;
|
||||||
|
pipeline.addAfter(context.invoker, oldName, name, e.handler);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (selfRemoval) {
|
if (selfRemoval) {
|
||||||
|
@ -175,6 +175,15 @@ public interface ChannelHandlerContext extends AttributeMap {
|
|||||||
*/
|
*/
|
||||||
ChannelHandlerContext fireChannelRegistered();
|
ChannelHandlerContext fireChannelRegistered();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Channel} was unregistered from its {@link EventLoop}.
|
||||||
|
*
|
||||||
|
* This will result in having the {@link ChannelHandler#channelUnregistered(ChannelHandlerContext)} method
|
||||||
|
* called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*/
|
||||||
|
ChannelHandlerContext fireChannelUnregistered();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Channel} is active now, which means it is connected.
|
* A {@link Channel} is active now, which means it is connected.
|
||||||
*
|
*
|
||||||
@ -295,6 +304,19 @@ public interface ChannelHandlerContext extends AttributeMap {
|
|||||||
*/
|
*/
|
||||||
ChannelFuture close();
|
ChannelFuture close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to deregister from the previous assigned {@link EventExecutor} and notify the
|
||||||
|
* {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
|
||||||
|
* an error.
|
||||||
|
* <p>
|
||||||
|
* This will result in having the
|
||||||
|
* {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
|
||||||
|
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ChannelFuture deregister();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
|
* Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
|
||||||
* completes, either because the operation was successful or because of an error.
|
* completes, either because the operation was successful or because of an error.
|
||||||
@ -368,6 +390,20 @@ public interface ChannelHandlerContext extends AttributeMap {
|
|||||||
*/
|
*/
|
||||||
ChannelFuture close(ChannelPromise promise);
|
ChannelFuture close(ChannelPromise promise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to deregister from the previous assigned {@link EventExecutor} and notify the
|
||||||
|
* {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
|
||||||
|
* an error.
|
||||||
|
*
|
||||||
|
* The given {@link ChannelPromise} will be notified.
|
||||||
|
* <p>
|
||||||
|
* This will result in having the
|
||||||
|
* {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
|
||||||
|
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*/
|
||||||
|
ChannelFuture deregister(ChannelPromise promise);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
|
* Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
|
||||||
* {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
|
* {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
|
||||||
|
@ -39,6 +39,13 @@ public interface ChannelHandlerInvoker {
|
|||||||
*/
|
*/
|
||||||
void invokeChannelRegistered(ChannelHandlerContext ctx);
|
void invokeChannelRegistered(ChannelHandlerContext ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes {@link ChannelHandler#channelUnregistered(ChannelHandlerContext)}. This method is not for a user
|
||||||
|
* but for the internal {@link ChannelHandlerContext} implementation. To trigger an event, use the methods in
|
||||||
|
* {@link ChannelHandlerContext} instead.
|
||||||
|
*/
|
||||||
|
void invokeChannelUnregistered(ChannelHandlerContext ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes {@link ChannelHandler#channelActive(ChannelHandlerContext)}. This method is not for a user
|
* Invokes {@link ChannelHandler#channelActive(ChannelHandlerContext)}. This method is not for a user
|
||||||
* but for the internal {@link ChannelHandlerContext} implementation. To trigger an event, use the methods in
|
* but for the internal {@link ChannelHandlerContext} implementation. To trigger an event, use the methods in
|
||||||
@ -118,6 +125,13 @@ public interface ChannelHandlerInvoker {
|
|||||||
*/
|
*/
|
||||||
void invokeClose(ChannelHandlerContext ctx, ChannelPromise promise);
|
void invokeClose(ChannelHandlerContext ctx, ChannelPromise promise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}.
|
||||||
|
* This method is not for a user but for the internal {@link ChannelHandlerContext} implementation.
|
||||||
|
* To trigger an event, use the methods in {@link ChannelHandlerContext} instead.
|
||||||
|
*/
|
||||||
|
void invokeDeregister(ChannelHandlerContext ctx, ChannelPromise promise);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes {@link ChannelHandler#read(ChannelHandlerContext)}.
|
* Invokes {@link ChannelHandler#read(ChannelHandlerContext)}.
|
||||||
* This method is not for a user but for the internal {@link ChannelHandlerContext} implementation.
|
* This method is not for a user but for the internal {@link ChannelHandlerContext} implementation.
|
||||||
|
@ -35,6 +35,14 @@ public final class ChannelHandlerInvokerUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void invokeChannelUnregisteredNow(ChannelHandlerContext ctx) {
|
||||||
|
try {
|
||||||
|
ctx.handler().channelUnregistered(ctx);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
notifyHandlerException(ctx, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void invokeChannelActiveNow(final ChannelHandlerContext ctx) {
|
public static void invokeChannelActiveNow(final ChannelHandlerContext ctx) {
|
||||||
try {
|
try {
|
||||||
ctx.handler().channelActive(ctx);
|
ctx.handler().channelActive(ctx);
|
||||||
@ -129,6 +137,14 @@ public final class ChannelHandlerInvokerUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void invokeDeregisterNow(final ChannelHandlerContext ctx, final ChannelPromise promise) {
|
||||||
|
try {
|
||||||
|
ctx.handler().deregister(ctx, promise);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
notifyOutboundHandlerException(t, promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void invokeReadNow(final ChannelHandlerContext ctx) {
|
public static void invokeReadNow(final ChannelHandlerContext ctx) {
|
||||||
try {
|
try {
|
||||||
ctx.handler().read(ctx);
|
ctx.handler().read(ctx);
|
||||||
|
@ -17,6 +17,7 @@ package io.netty.channel;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.util.concurrent.DefaultEventExecutorGroup;
|
import io.netty.util.concurrent.DefaultEventExecutorGroup;
|
||||||
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.EventExecutorGroup;
|
import io.netty.util.concurrent.EventExecutorGroup;
|
||||||
|
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
@ -661,6 +662,15 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
|||||||
*/
|
*/
|
||||||
ChannelPipeline fireChannelRegistered();
|
ChannelPipeline fireChannelRegistered();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link Channel} was unregistered from its {@link EventLoop}.
|
||||||
|
*
|
||||||
|
* This will result in having the {@link ChannelHandler#channelUnregistered(ChannelHandlerContext)} method
|
||||||
|
* called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*/
|
||||||
|
ChannelPipeline fireChannelUnregistered();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Channel} is active now, which means it is connected.
|
* A {@link Channel} is active now, which means it is connected.
|
||||||
*
|
*
|
||||||
@ -781,6 +791,19 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
|||||||
*/
|
*/
|
||||||
ChannelFuture close();
|
ChannelFuture close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to deregister the {@link Channel} from the previous assigned {@link EventExecutor} and notify the
|
||||||
|
* {@link ChannelFuture} once the operation completes, either because the operation was successful or because of
|
||||||
|
* an error.
|
||||||
|
* <p>
|
||||||
|
* This will result in having the
|
||||||
|
* {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
|
||||||
|
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ChannelFuture deregister();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
|
* Request to bind to the given {@link SocketAddress} and notify the {@link ChannelFuture} once the operation
|
||||||
* completes, either because the operation was successful or because of an error.
|
* completes, either because the operation was successful or because of an error.
|
||||||
@ -854,6 +877,20 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
|||||||
*/
|
*/
|
||||||
ChannelFuture close(ChannelPromise promise);
|
ChannelFuture close(ChannelPromise promise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to deregister the {@link Channel} bound this {@link ChannelPipeline} from the previous assigned
|
||||||
|
* {@link EventExecutor} and notify the {@link ChannelFuture} once the operation completes, either because the
|
||||||
|
* operation was successful or because of an error.
|
||||||
|
*
|
||||||
|
* The given {@link ChannelPromise} will be notified.
|
||||||
|
* <p>ChannelOutboundHandler
|
||||||
|
* This will result in having the
|
||||||
|
* {@link ChannelHandler#deregister(ChannelHandlerContext, ChannelPromise)}
|
||||||
|
* method called of the next {@link ChannelHandler} contained in the {@link ChannelPipeline} of the
|
||||||
|
* {@link Channel}.
|
||||||
|
*/
|
||||||
|
ChannelFuture deregister(ChannelPromise promise);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
|
* Request to Read data from the {@link Channel} into the first inbound buffer, triggers an
|
||||||
* {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
|
* {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
|
||||||
|
@ -38,19 +38,21 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
static final int MASK_HANDLER_REMOVED = 1 << 1;
|
static final int MASK_HANDLER_REMOVED = 1 << 1;
|
||||||
private static final int MASK_EXCEPTION_CAUGHT = 1 << 2;
|
private static final int MASK_EXCEPTION_CAUGHT = 1 << 2;
|
||||||
private static final int MASK_CHANNEL_REGISTERED = 1 << 3;
|
private static final int MASK_CHANNEL_REGISTERED = 1 << 3;
|
||||||
private static final int MASK_CHANNEL_ACTIVE = 1 << 4;
|
private static final int MASK_CHANNEL_UNREGISTERED = 1 << 4;
|
||||||
private static final int MASK_CHANNEL_INACTIVE = 1 << 5;
|
private static final int MASK_CHANNEL_ACTIVE = 1 << 5;
|
||||||
private static final int MASK_CHANNEL_READ = 1 << 6;
|
private static final int MASK_CHANNEL_INACTIVE = 1 << 6;
|
||||||
private static final int MASK_CHANNEL_READ_COMPLETE = 1 << 7;
|
private static final int MASK_CHANNEL_READ = 1 << 7;
|
||||||
private static final int MASK_CHANNEL_WRITABILITY_CHANGED = 1 << 8;
|
private static final int MASK_CHANNEL_READ_COMPLETE = 1 << 8;
|
||||||
private static final int MASK_USER_EVENT_TRIGGERED = 1 << 9;
|
private static final int MASK_CHANNEL_WRITABILITY_CHANGED = 1 << 9;
|
||||||
private static final int MASK_BIND = 1 << 10;
|
private static final int MASK_USER_EVENT_TRIGGERED = 1 << 10;
|
||||||
private static final int MASK_CONNECT = 1 << 11;
|
private static final int MASK_BIND = 1 << 11;
|
||||||
private static final int MASK_DISCONNECT = 1 << 12;
|
private static final int MASK_CONNECT = 1 << 12;
|
||||||
private static final int MASK_CLOSE = 1 << 13;
|
private static final int MASK_DISCONNECT = 1 << 13;
|
||||||
private static final int MASK_READ = 1 << 14;
|
private static final int MASK_CLOSE = 1 << 14;
|
||||||
private static final int MASK_WRITE = 1 << 15;
|
private static final int MASK_DEREGISTER = 1 << 15;
|
||||||
private static final int MASK_FLUSH = 1 << 16;
|
private static final int MASK_READ = 1 << 16;
|
||||||
|
private static final int MASK_WRITE = 1 << 17;
|
||||||
|
private static final int MASK_FLUSH = 1 << 18;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache the result of the costly generation of {@link #skipFlags} in the partitioned synchronized
|
* Cache the result of the costly generation of {@link #skipFlags} in the partitioned synchronized
|
||||||
@ -111,6 +113,10 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
"channelRegistered", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
"channelRegistered", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||||
flags |= MASK_CHANNEL_REGISTERED;
|
flags |= MASK_CHANNEL_REGISTERED;
|
||||||
}
|
}
|
||||||
|
if (handlerType.getMethod(
|
||||||
|
"channelUnregistered", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||||
|
flags |= MASK_CHANNEL_UNREGISTERED;
|
||||||
|
}
|
||||||
if (handlerType.getMethod(
|
if (handlerType.getMethod(
|
||||||
"channelActive", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
"channelActive", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||||
flags |= MASK_CHANNEL_ACTIVE;
|
flags |= MASK_CHANNEL_ACTIVE;
|
||||||
@ -153,6 +159,10 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
"close", ChannelHandlerContext.class, ChannelPromise.class).isAnnotationPresent(Skip.class)) {
|
"close", ChannelHandlerContext.class, ChannelPromise.class).isAnnotationPresent(Skip.class)) {
|
||||||
flags |= MASK_CLOSE;
|
flags |= MASK_CLOSE;
|
||||||
}
|
}
|
||||||
|
if (handlerType.getMethod(
|
||||||
|
"deregister", ChannelHandlerContext.class, ChannelPromise.class).isAnnotationPresent(Skip.class)) {
|
||||||
|
flags |= MASK_DEREGISTER;
|
||||||
|
}
|
||||||
if (handlerType.getMethod(
|
if (handlerType.getMethod(
|
||||||
"read", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
"read", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||||
flags |= MASK_READ;
|
flags |= MASK_READ;
|
||||||
@ -215,14 +225,9 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
this.pipeline = pipeline;
|
this.pipeline = pipeline;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
|
this.invoker = invoker;
|
||||||
|
|
||||||
skipFlags = skipFlags(handler);
|
skipFlags = skipFlags(handler);
|
||||||
|
|
||||||
if (invoker == null) {
|
|
||||||
this.invoker = channel.unsafe().invoker();
|
|
||||||
} else {
|
|
||||||
this.invoker = invoker;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Invocation initiated by {@link DefaultChannelPipeline#teardownAll()}}. */
|
/** Invocation initiated by {@link DefaultChannelPipeline#teardownAll()}}. */
|
||||||
@ -267,11 +272,14 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventExecutor executor() {
|
public EventExecutor executor() {
|
||||||
return invoker.executor();
|
return invoker().executor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerInvoker invoker() {
|
public ChannelHandlerInvoker invoker() {
|
||||||
|
if (invoker == null) {
|
||||||
|
return channel.unsafe().invoker();
|
||||||
|
}
|
||||||
return invoker;
|
return invoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -293,35 +301,42 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext fireChannelRegistered() {
|
public ChannelHandlerContext fireChannelRegistered() {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_REGISTERED);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_REGISTERED);
|
||||||
next.invoker.invokeChannelRegistered(next);
|
next.invoker().invokeChannelRegistered(next);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelHandlerContext fireChannelUnregistered() {
|
||||||
|
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_UNREGISTERED);
|
||||||
|
next.invoker().invokeChannelUnregistered(next);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext fireChannelActive() {
|
public ChannelHandlerContext fireChannelActive() {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_ACTIVE);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_ACTIVE);
|
||||||
next.invoker.invokeChannelActive(next);
|
next.invoker().invokeChannelActive(next);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext fireChannelInactive() {
|
public ChannelHandlerContext fireChannelInactive() {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_INACTIVE);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_INACTIVE);
|
||||||
next.invoker.invokeChannelInactive(next);
|
next.invoker().invokeChannelInactive(next);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext fireExceptionCaught(Throwable cause) {
|
public ChannelHandlerContext fireExceptionCaught(Throwable cause) {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_EXCEPTION_CAUGHT);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_EXCEPTION_CAUGHT);
|
||||||
next.invoker.invokeExceptionCaught(next, cause);
|
next.invoker().invokeExceptionCaught(next, cause);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext fireUserEventTriggered(Object event) {
|
public ChannelHandlerContext fireUserEventTriggered(Object event) {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_USER_EVENT_TRIGGERED);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_USER_EVENT_TRIGGERED);
|
||||||
next.invoker.invokeUserEventTriggered(next, event);
|
next.invoker().invokeUserEventTriggered(next, event);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,21 +344,21 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
public ChannelHandlerContext fireChannelRead(Object msg) {
|
public ChannelHandlerContext fireChannelRead(Object msg) {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_READ);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_READ);
|
||||||
ReferenceCountUtil.touch(msg, next);
|
ReferenceCountUtil.touch(msg, next);
|
||||||
next.invoker.invokeChannelRead(next, msg);
|
next.invoker().invokeChannelRead(next, msg);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext fireChannelReadComplete() {
|
public ChannelHandlerContext fireChannelReadComplete() {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_READ_COMPLETE);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_READ_COMPLETE);
|
||||||
next.invoker.invokeChannelReadComplete(next);
|
next.invoker().invokeChannelReadComplete(next);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext fireChannelWritabilityChanged() {
|
public ChannelHandlerContext fireChannelWritabilityChanged() {
|
||||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_WRITABILITY_CHANGED);
|
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_WRITABILITY_CHANGED);
|
||||||
next.invoker.invokeChannelWritabilityChanged(next);
|
next.invoker().invokeChannelWritabilityChanged(next);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,10 +387,15 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
return close(newPromise());
|
return close(newPromise());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture deregister() {
|
||||||
|
return deregister(newPromise());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelFuture bind(final SocketAddress localAddress, final ChannelPromise promise) {
|
public ChannelFuture bind(final SocketAddress localAddress, final ChannelPromise promise) {
|
||||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_BIND);
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_BIND);
|
||||||
next.invoker.invokeBind(next, localAddress, promise);
|
next.invoker().invokeBind(next, localAddress, promise);
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +407,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
@Override
|
@Override
|
||||||
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
|
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
|
||||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_CONNECT);
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_CONNECT);
|
||||||
next.invoker.invokeConnect(next, remoteAddress, localAddress, promise);
|
next.invoker().invokeConnect(next, remoteAddress, localAddress, promise);
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,21 +418,28 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
}
|
}
|
||||||
|
|
||||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_DISCONNECT);
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_DISCONNECT);
|
||||||
next.invoker.invokeDisconnect(next, promise);
|
next.invoker().invokeDisconnect(next, promise);
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelFuture close(ChannelPromise promise) {
|
public ChannelFuture close(ChannelPromise promise) {
|
||||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_CLOSE);
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_CLOSE);
|
||||||
next.invoker.invokeClose(next, promise);
|
next.invoker().invokeClose(next, promise);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture deregister(ChannelPromise promise) {
|
||||||
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_DEREGISTER);
|
||||||
|
next.invoker().invokeDeregister(next, promise);
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext read() {
|
public ChannelHandlerContext read() {
|
||||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_READ);
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_READ);
|
||||||
next.invoker.invokeRead(next);
|
next.invoker().invokeRead(next);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,14 +452,14 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
public ChannelFuture write(Object msg, ChannelPromise promise) {
|
public ChannelFuture write(Object msg, ChannelPromise promise) {
|
||||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_WRITE);
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_WRITE);
|
||||||
ReferenceCountUtil.touch(msg, next);
|
ReferenceCountUtil.touch(msg, next);
|
||||||
next.invoker.invokeWrite(next, msg, promise);
|
next.invoker().invokeWrite(next, msg, promise);
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelHandlerContext flush() {
|
public ChannelHandlerContext flush() {
|
||||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_FLUSH);
|
DefaultChannelHandlerContext next = findContextOutbound(MASK_FLUSH);
|
||||||
next.invoker.invokeFlush(next);
|
next.invoker().invokeFlush(next);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,9 +468,9 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
|||||||
DefaultChannelHandlerContext next;
|
DefaultChannelHandlerContext next;
|
||||||
next = findContextOutbound(MASK_WRITE);
|
next = findContextOutbound(MASK_WRITE);
|
||||||
ReferenceCountUtil.touch(msg, next);
|
ReferenceCountUtil.touch(msg, next);
|
||||||
next.invoker.invokeWrite(next, msg, promise);
|
next.invoker().invokeWrite(next, msg, promise);
|
||||||
next = findContextOutbound(MASK_FLUSH);
|
next = findContextOutbound(MASK_FLUSH);
|
||||||
next.invoker.invokeFlush(next);
|
next.invoker().invokeFlush(next);
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,20 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invokeChannelUnregistered(final ChannelHandlerContext ctx) {
|
||||||
|
if (executor.inEventLoop()) {
|
||||||
|
invokeChannelUnregisteredNow(ctx);
|
||||||
|
} else {
|
||||||
|
executor.execute(new OneTimeTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
invokeChannelUnregisteredNow(ctx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invokeChannelActive(final ChannelHandlerContext ctx) {
|
public void invokeChannelActive(final ChannelHandlerContext ctx) {
|
||||||
if (executor.inEventLoop()) {
|
if (executor.inEventLoop()) {
|
||||||
@ -269,6 +283,25 @@ public class DefaultChannelHandlerInvoker implements ChannelHandlerInvoker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invokeDeregister(final ChannelHandlerContext ctx, final ChannelPromise promise) {
|
||||||
|
if (!validatePromise(ctx, promise, false)) {
|
||||||
|
// promise cancelled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (executor.inEventLoop()) {
|
||||||
|
invokeDeregisterNow(ctx, promise);
|
||||||
|
} else {
|
||||||
|
safeExecuteOutbound(new OneTimeTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
invokeDeregisterNow(ctx, promise);
|
||||||
|
}
|
||||||
|
}, promise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invokeRead(final ChannelHandlerContext ctx) {
|
public void invokeRead(final ChannelHandlerContext ctx) {
|
||||||
if (executor.inEventLoop()) {
|
if (executor.inEventLoop()) {
|
||||||
|
@ -550,6 +550,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
try {
|
try {
|
||||||
ctx.handler().handlerAdded(ctx);
|
ctx.handler().handlerAdded(ctx);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
t.printStackTrace();
|
||||||
boolean removed = false;
|
boolean removed = false;
|
||||||
try {
|
try {
|
||||||
remove(ctx);
|
remove(ctx);
|
||||||
@ -802,6 +803,17 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelPipeline fireChannelUnregistered() {
|
||||||
|
head.fireChannelUnregistered();
|
||||||
|
|
||||||
|
// Remove all handlers sequentially if channel is closed and unregistered.
|
||||||
|
if (!channel.isOpen()) {
|
||||||
|
teardownAll();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all handlers from the pipeline one by one from tail (exclusive) to head (inclusive) to trigger
|
* Removes all handlers from the pipeline one by one from tail (exclusive) to head (inclusive) to trigger
|
||||||
* handlerRemoved(). Note that the tail handler is excluded because it's neither an outbound handler nor it
|
* handlerRemoved(). Note that the tail handler is excluded because it's neither an outbound handler nor it
|
||||||
@ -825,7 +837,6 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
@Override
|
@Override
|
||||||
public ChannelPipeline fireChannelInactive() {
|
public ChannelPipeline fireChannelInactive() {
|
||||||
head.fireChannelInactive();
|
head.fireChannelInactive();
|
||||||
teardownAll();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -887,6 +898,11 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
return tail.close();
|
return tail.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture deregister() {
|
||||||
|
return tail.deregister();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelPipeline flush() {
|
public ChannelPipeline flush() {
|
||||||
tail.flush();
|
tail.flush();
|
||||||
@ -918,6 +934,11 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
return tail.close(promise);
|
return tail.close(promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture deregister(ChannelPromise promise) {
|
||||||
|
return tail.close(promise);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelPipeline read() {
|
public ChannelPipeline read() {
|
||||||
tail.read();
|
tail.read();
|
||||||
@ -983,6 +1004,9 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
@Override
|
@Override
|
||||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception { }
|
public void channelRegistered(ChannelHandlerContext ctx) throws Exception { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx) throws Exception { }
|
public void channelActive(ChannelHandlerContext ctx) throws Exception { }
|
||||||
|
|
||||||
@ -1050,6 +1074,11 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
|||||||
unsafe.close(promise);
|
unsafe.close(promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
|
||||||
|
unsafe.deregister(promise);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ChannelHandlerContext ctx) {
|
public void read(ChannelHandlerContext ctx) {
|
||||||
unsafe.beginRead();
|
unsafe.beginRead();
|
||||||
|
@ -25,4 +25,16 @@ import io.netty.util.concurrent.EventExecutorGroup;
|
|||||||
public interface EventLoopGroup extends EventExecutorGroup {
|
public interface EventLoopGroup extends EventExecutorGroup {
|
||||||
@Override
|
@Override
|
||||||
EventLoop next();
|
EventLoop next();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a {@link Channel} with this {@link EventLoop}. The returned {@link ChannelFuture}
|
||||||
|
* will get notified once the registration was complete.
|
||||||
|
*/
|
||||||
|
ChannelFuture register(Channel channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a {@link Channel} with this {@link EventLoop}. The passed {@link ChannelFuture}
|
||||||
|
* will get notified once the registration was complete and also will get returned.
|
||||||
|
*/
|
||||||
|
ChannelFuture register(Channel channel, ChannelPromise promise);
|
||||||
}
|
}
|
||||||
|
@ -69,5 +69,12 @@ public abstract class MultithreadEventLoopGroup extends MultithreadEventExecutor
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected abstract EventLoop newChild(Executor executor, Object... args) throws Exception;
|
public ChannelFuture register(Channel channel) {
|
||||||
|
return next().register(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(Channel channel, ChannelPromise promise) {
|
||||||
|
return next().register(channel, promise);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,8 @@ package io.netty.channel;
|
|||||||
import io.netty.channel.socket.ServerSocketChannel;
|
import io.netty.channel.socket.ServerSocketChannel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link Channel} that accepts an incoming connection attempt and creates its child {@link Channel}s by accepting
|
* A {@link Channel} that accepts an incoming connection attempt and creates
|
||||||
* them. {@link ServerSocketChannel} is a good example.
|
* its child {@link Channel}s by accepting them. {@link ServerSocketChannel} is
|
||||||
|
* a good example.
|
||||||
*/
|
*/
|
||||||
public interface ServerChannel extends Channel {
|
public interface ServerChannel extends Channel { }
|
||||||
EventLoopGroup childEventLoopGroup();
|
|
||||||
}
|
|
||||||
|
@ -51,6 +51,24 @@ public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor im
|
|||||||
return invoker;
|
return invoker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(Channel channel) {
|
||||||
|
return register(channel, new DefaultChannelPromise(channel, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(final Channel channel, final ChannelPromise promise) {
|
||||||
|
if (channel == null) {
|
||||||
|
throw new NullPointerException("channel");
|
||||||
|
}
|
||||||
|
if (promise == null) {
|
||||||
|
throw new NullPointerException("promise");
|
||||||
|
}
|
||||||
|
|
||||||
|
channel.unsafe().register(this, promise);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean wakesUpForTask(Runnable task) {
|
protected boolean wakesUpForTask(Runnable task) {
|
||||||
return !(task instanceof NonWakeupRunnable);
|
return !(task instanceof NonWakeupRunnable);
|
||||||
|
@ -30,6 +30,21 @@ public class ThreadPerChannelEventLoop extends SingleThreadEventLoop {
|
|||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(Channel channel, ChannelPromise promise) {
|
||||||
|
return super.register(channel, promise).addListener(new ChannelFutureListener() {
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
|
if (future.isSuccess()) {
|
||||||
|
ch = future.channel();
|
||||||
|
} else {
|
||||||
|
deregister();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void run() {
|
protected void run() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package io.netty.channel;
|
package io.netty.channel;
|
||||||
|
|
||||||
|
|
||||||
|
import io.netty.util.concurrent.AbstractEventExecutorGroup;
|
||||||
import io.netty.util.concurrent.DefaultPromise;
|
import io.netty.util.concurrent.DefaultPromise;
|
||||||
import io.netty.util.concurrent.EventExecutor;
|
import io.netty.util.concurrent.EventExecutor;
|
||||||
import io.netty.util.concurrent.Future;
|
import io.netty.util.concurrent.Future;
|
||||||
@ -39,13 +40,14 @@ import java.util.concurrent.TimeUnit;
|
|||||||
/**
|
/**
|
||||||
* An {@link EventLoopGroup} that creates one {@link EventLoop} per {@link Channel}.
|
* An {@link EventLoopGroup} that creates one {@link EventLoop} per {@link Channel}.
|
||||||
*/
|
*/
|
||||||
public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
public class ThreadPerChannelEventLoopGroup extends AbstractEventExecutorGroup implements EventLoopGroup {
|
||||||
|
|
||||||
private final Object[] childArgs;
|
private final Object[] childArgs;
|
||||||
private final int maxChannels;
|
private final int maxChannels;
|
||||||
final Executor executor;
|
final Executor executor;
|
||||||
final Set<EventLoop> activeChildren =
|
final Set<EventLoop> activeChildren =
|
||||||
Collections.newSetFromMap(PlatformDependent.<EventLoop, Boolean>newConcurrentHashMap());
|
Collections.newSetFromMap(PlatformDependent.<EventLoop, Boolean>newConcurrentHashMap());
|
||||||
|
private final Set<EventLoop> readOnlyActiveChildren = Collections.unmodifiableSet(activeChildren);
|
||||||
final Queue<EventLoop> idleChildren = new ConcurrentLinkedQueue<EventLoop>();
|
final Queue<EventLoop> idleChildren = new ConcurrentLinkedQueue<EventLoop>();
|
||||||
private final ChannelException tooManyChannels;
|
private final ChannelException tooManyChannels;
|
||||||
|
|
||||||
@ -73,7 +75,9 @@ public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
|||||||
*
|
*
|
||||||
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
||||||
* a new {@link Channel} and the maximum is exceed it will throw an
|
* a new {@link Channel} and the maximum is exceed it will throw an
|
||||||
* {@link ChannelException}. Use {@code 0} to use no limit
|
* {@link ChannelException}. on the {@link #register(Channel)} and
|
||||||
|
* {@link #register(Channel, ChannelPromise)} method.
|
||||||
|
* Use {@code 0} to use no limit
|
||||||
*/
|
*/
|
||||||
protected ThreadPerChannelEventLoopGroup(int maxChannels) {
|
protected ThreadPerChannelEventLoopGroup(int maxChannels) {
|
||||||
this(maxChannels, Executors.defaultThreadFactory());
|
this(maxChannels, Executors.defaultThreadFactory());
|
||||||
@ -84,7 +88,9 @@ public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
|||||||
*
|
*
|
||||||
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
||||||
* a new {@link Channel} and the maximum is exceed it will throw an
|
* a new {@link Channel} and the maximum is exceed it will throw an
|
||||||
* {@link ChannelException}. Use {@code 0} to use no limit
|
* {@link ChannelException} on the {@link #register(Channel)} and
|
||||||
|
* {@link #register(Channel, ChannelPromise)} method.
|
||||||
|
* Use {@code 0} to use no limit
|
||||||
* @param threadFactory the {@link ThreadFactory} used to create new {@link Thread} instances that handle the
|
* @param threadFactory the {@link ThreadFactory} used to create new {@link Thread} instances that handle the
|
||||||
* registered {@link Channel}s
|
* registered {@link Channel}s
|
||||||
* @param args arguments which will passed to each {@link #newChild(Object...)} call.
|
* @param args arguments which will passed to each {@link #newChild(Object...)} call.
|
||||||
@ -98,7 +104,9 @@ public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
|||||||
*
|
*
|
||||||
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
* @param maxChannels the maximum number of channels to handle with this instance. Once you try to register
|
||||||
* a new {@link Channel} and the maximum is exceed it will throw an
|
* a new {@link Channel} and the maximum is exceed it will throw an
|
||||||
* {@link ChannelException}. Use {@code 0} to use no limit
|
* {@link ChannelException} on the {@link #register(Channel)} and
|
||||||
|
* {@link #register(Channel, ChannelPromise)} method.
|
||||||
|
* Use {@code 0} to use no limit
|
||||||
* @param executor the {@link Executor} used to create new {@link Thread} instances that handle the
|
* @param executor the {@link Executor} used to create new {@link Thread} instances that handle the
|
||||||
* registered {@link Channel}s
|
* registered {@link Channel}s
|
||||||
* @param args arguments which will passed to each {@link #newChild(Object...)} call.
|
* @param args arguments which will passed to each {@link #newChild(Object...)} call.
|
||||||
@ -126,34 +134,21 @@ public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link EventLoop}.
|
* Creates a new {@link EventLoop}. The default implementation creates a new {@link ThreadPerChannelEventLoop}.
|
||||||
*/
|
*/
|
||||||
protected EventLoop newChild(@SuppressWarnings("UnusedParameters") Object... args) {
|
protected EventLoop newChild(@SuppressWarnings("UnusedParameters") Object... args) throws Exception {
|
||||||
return new ThreadPerChannelEventLoop(this);
|
return new ThreadPerChannelEventLoop(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <E extends EventExecutor> Set<E> children() {
|
public <E extends EventExecutor> Set<E> children() {
|
||||||
return Collections.unmodifiableSet((Set<E>) activeChildren);
|
return (Set<E>) readOnlyActiveChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EventLoop next() {
|
public EventLoop next() {
|
||||||
if (shuttingDown) {
|
throw new UnsupportedOperationException();
|
||||||
throw new RejectedExecutionException("shutting down");
|
|
||||||
}
|
|
||||||
|
|
||||||
EventLoop loop = idleChildren.poll();
|
|
||||||
if (loop == null) {
|
|
||||||
if (maxChannels > 0 && activeChildren.size() >= maxChannels) {
|
|
||||||
throw tooManyChannels;
|
|
||||||
}
|
|
||||||
loop = newChild(childArgs);
|
|
||||||
loop.terminationFuture().addListener(childTerminationListener);
|
|
||||||
}
|
|
||||||
activeChildren.add(loop);
|
|
||||||
return loop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -271,4 +266,47 @@ public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
|||||||
}
|
}
|
||||||
return isTerminated();
|
return isTerminated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(Channel channel) {
|
||||||
|
if (channel == null) {
|
||||||
|
throw new NullPointerException("channel");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
EventLoop l = nextChild();
|
||||||
|
return l.register(channel, new DefaultChannelPromise(channel, l));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
return new FailedChannelFuture(channel, GlobalEventExecutor.INSTANCE, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(Channel channel, ChannelPromise promise) {
|
||||||
|
if (channel == null) {
|
||||||
|
throw new NullPointerException("channel");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return nextChild().register(channel, promise);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
promise.setFailure(t);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventLoop nextChild() throws Exception {
|
||||||
|
if (shuttingDown) {
|
||||||
|
throw new RejectedExecutionException("shutting down");
|
||||||
|
}
|
||||||
|
|
||||||
|
EventLoop loop = idleChildren.poll();
|
||||||
|
if (loop == null) {
|
||||||
|
if (maxChannels > 0 && activeChildren.size() >= maxChannels) {
|
||||||
|
throw tooManyChannels;
|
||||||
|
}
|
||||||
|
loop = newChild(childArgs);
|
||||||
|
loop.terminationFuture().addListener(childTerminationListener);
|
||||||
|
}
|
||||||
|
activeChildren.add(loop);
|
||||||
|
return loop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,172 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 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 io.netty.channel;
|
|
||||||
|
|
||||||
import io.netty.util.concurrent.Future;
|
|
||||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
|
||||||
import io.netty.util.internal.StringUtil;
|
|
||||||
|
|
||||||
import java.net.SocketAddress;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link Channel} that represents a non-existing {@link Channel} which could not be instantiated successfully.
|
|
||||||
*/
|
|
||||||
public final class VoidChannel extends AbstractChannel {
|
|
||||||
|
|
||||||
public static final VoidChannel INSTANCE = new VoidChannel();
|
|
||||||
|
|
||||||
private VoidChannel() {
|
|
||||||
super(null, new AbstractEventLoop(null) {
|
|
||||||
private final ChannelHandlerInvoker invoker =
|
|
||||||
new DefaultChannelHandlerInvoker(GlobalEventExecutor.INSTANCE);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Deprecated
|
|
||||||
public void shutdown() {
|
|
||||||
GlobalEventExecutor.INSTANCE.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelHandlerInvoker asInvoker() {
|
|
||||||
return invoker;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean inEventLoop(Thread thread) {
|
|
||||||
return GlobalEventExecutor.INSTANCE.inEventLoop(thread);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isShuttingDown() {
|
|
||||||
return GlobalEventExecutor.INSTANCE.isShuttingDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Future<?> shutdownGracefully(long quietPeriod, long timeout, TimeUnit unit) {
|
|
||||||
return GlobalEventExecutor.INSTANCE.shutdownGracefully(quietPeriod, timeout, unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Future<?> terminationFuture() {
|
|
||||||
return GlobalEventExecutor.INSTANCE.terminationFuture();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isShutdown() {
|
|
||||||
return GlobalEventExecutor.INSTANCE.isShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isTerminated() {
|
|
||||||
return GlobalEventExecutor.INSTANCE.isTerminated();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
|
|
||||||
return GlobalEventExecutor.INSTANCE.awaitTermination(timeout, unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Runnable command) {
|
|
||||||
GlobalEventExecutor.INSTANCE.execute(command);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AbstractUnsafe newUnsafe() {
|
|
||||||
return new AbstractUnsafe() {
|
|
||||||
@Override
|
|
||||||
public void connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isCompatible(EventLoop loop) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SocketAddress localAddress0() {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected SocketAddress remoteAddress0() {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doBind(SocketAddress localAddress) throws Exception {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doDisconnect() throws Exception {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doClose() throws Exception {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doBeginRead() throws Exception {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doWrite(ChannelOutboundBuffer in) throws Exception {
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelConfig config() {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpen() {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isActive() {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChannelMetadata metadata() {
|
|
||||||
return reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return StringUtil.simpleClassName(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static <T> T reject() {
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
StringUtil.simpleClassName(VoidChannel.class) +
|
|
||||||
" is only for the representation of a non-existing " +
|
|
||||||
StringUtil.simpleClassName(Channel.class) + '.');
|
|
||||||
}
|
|
||||||
}
|
|
@ -54,7 +54,7 @@ public class EmbeddedChannel extends AbstractChannel {
|
|||||||
|
|
||||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||||
|
|
||||||
private final EmbeddedEventLoop loop;
|
private final EmbeddedEventLoop loop = new EmbeddedEventLoop();
|
||||||
private final ChannelConfig config = new DefaultChannelConfig(this);
|
private final ChannelConfig config = new DefaultChannelConfig(this);
|
||||||
private final Queue<Object> inboundMessages = new ArrayDeque<Object>();
|
private final Queue<Object> inboundMessages = new ArrayDeque<Object>();
|
||||||
private final Queue<Object> outboundMessages = new ArrayDeque<Object>();
|
private final Queue<Object> outboundMessages = new ArrayDeque<Object>();
|
||||||
@ -74,9 +74,7 @@ public class EmbeddedChannel extends AbstractChannel {
|
|||||||
* @param handlers the @link ChannelHandler}s which will be add in the {@link ChannelPipeline}
|
* @param handlers the @link ChannelHandler}s which will be add in the {@link ChannelPipeline}
|
||||||
*/
|
*/
|
||||||
public EmbeddedChannel(ChannelHandler... handlers) {
|
public EmbeddedChannel(ChannelHandler... handlers) {
|
||||||
super(null, new EmbeddedEventLoop());
|
super(null);
|
||||||
|
|
||||||
loop = (EmbeddedEventLoop) eventLoop();
|
|
||||||
|
|
||||||
if (handlers == null) {
|
if (handlers == null) {
|
||||||
throw new NullPointerException("handlers");
|
throw new NullPointerException("handlers");
|
||||||
@ -91,7 +89,7 @@ public class EmbeddedChannel extends AbstractChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.addLast(new LastInboundHandler());
|
p.addLast(new LastInboundHandler());
|
||||||
unsafe().register(newPromise());
|
loop.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
package io.netty.channel.embedded;
|
package io.netty.channel.embedded;
|
||||||
|
|
||||||
import io.netty.channel.AbstractEventLoop;
|
import io.netty.channel.AbstractEventLoop;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelHandlerInvoker;
|
import io.netty.channel.ChannelHandlerInvoker;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
@ -92,6 +94,17 @@ final class EmbeddedEventLoop extends AbstractEventLoop implements ChannelHandle
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(Channel channel) {
|
||||||
|
return register(channel, channel.newPromise());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelFuture register(Channel channel, ChannelPromise promise) {
|
||||||
|
channel.unsafe().register(this, promise);
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean inEventLoop() {
|
public boolean inEventLoop() {
|
||||||
return true;
|
return true;
|
||||||
@ -117,6 +130,11 @@ final class EmbeddedEventLoop extends AbstractEventLoop implements ChannelHandle
|
|||||||
invokeChannelRegisteredNow(ctx);
|
invokeChannelRegisteredNow(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invokeChannelUnregistered(ChannelHandlerContext ctx) {
|
||||||
|
invokeChannelUnregisteredNow(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invokeChannelActive(ChannelHandlerContext ctx) {
|
public void invokeChannelActive(ChannelHandlerContext ctx) {
|
||||||
invokeChannelActiveNow(ctx);
|
invokeChannelActiveNow(ctx);
|
||||||
@ -174,6 +192,11 @@ final class EmbeddedEventLoop extends AbstractEventLoop implements ChannelHandle
|
|||||||
invokeCloseNow(ctx, promise);
|
invokeCloseNow(ctx, promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invokeDeregister(ChannelHandlerContext ctx, ChannelPromise promise) {
|
||||||
|
invokeDeregisterNow(ctx, promise);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invokeRead(ChannelHandlerContext ctx) {
|
public void invokeRead(ChannelHandlerContext ctx) {
|
||||||
invokeReadNow(ctx);
|
invokeReadNow(ctx);
|
||||||
|
@ -87,12 +87,12 @@ public class LocalChannel extends AbstractChannel {
|
|||||||
private volatile boolean readInProgress;
|
private volatile boolean readInProgress;
|
||||||
private volatile boolean registerInProgress;
|
private volatile boolean registerInProgress;
|
||||||
|
|
||||||
public LocalChannel(EventLoop eventLoop) {
|
public LocalChannel() {
|
||||||
super(null, eventLoop);
|
super(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalChannel(LocalServerChannel parent, EventLoop eventLoop, LocalChannel peer) {
|
LocalChannel(LocalServerChannel parent, LocalChannel peer) {
|
||||||
super(parent, eventLoop);
|
super(parent);
|
||||||
this.peer = peer;
|
this.peer = peer;
|
||||||
localAddress = parent.localAddress();
|
localAddress = parent.localAddress();
|
||||||
remoteAddress = peer.localAddress();
|
remoteAddress = peer.localAddress();
|
||||||
|
@ -20,7 +20,6 @@ import io.netty.channel.ChannelConfig;
|
|||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.DefaultChannelConfig;
|
import io.netty.channel.DefaultChannelConfig;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.ServerChannel;
|
import io.netty.channel.ServerChannel;
|
||||||
import io.netty.channel.SingleThreadEventLoop;
|
import io.netty.channel.SingleThreadEventLoop;
|
||||||
import io.netty.util.concurrent.SingleThreadEventExecutor;
|
import io.netty.util.concurrent.SingleThreadEventExecutor;
|
||||||
@ -47,10 +46,6 @@ public class LocalServerChannel extends AbstractServerChannel {
|
|||||||
private volatile LocalAddress localAddress;
|
private volatile LocalAddress localAddress;
|
||||||
private volatile boolean acceptInProgress;
|
private volatile boolean acceptInProgress;
|
||||||
|
|
||||||
public LocalServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
|
||||||
super(eventLoop, childGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChannelConfig config() {
|
public ChannelConfig config() {
|
||||||
return config;
|
return config;
|
||||||
@ -136,7 +131,7 @@ public class LocalServerChannel extends AbstractServerChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LocalChannel serve(final LocalChannel peer) {
|
LocalChannel serve(final LocalChannel peer) {
|
||||||
final LocalChannel child = new LocalChannel(this, childEventLoopGroup().next(), peer);
|
final LocalChannel child = new LocalChannel(this, peer);
|
||||||
if (eventLoop().inEventLoop()) {
|
if (eventLoop().inEventLoop()) {
|
||||||
serve0(child);
|
serve0(child);
|
||||||
} else {
|
} else {
|
||||||
|
@ -22,7 +22,6 @@ import io.netty.channel.ChannelConfig;
|
|||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.FileRegion;
|
import io.netty.channel.FileRegion;
|
||||||
import io.netty.channel.RecvByteBufAllocator;
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
import io.netty.channel.socket.ChannelInputShutdownEvent;
|
import io.netty.channel.socket.ChannelInputShutdownEvent;
|
||||||
@ -44,8 +43,8 @@ public abstract class AbstractNioByteChannel extends AbstractNioChannel {
|
|||||||
* @param parent the parent {@link Channel} by which this instance was created. May be {@code null}
|
* @param parent the parent {@link Channel} by which this instance was created. May be {@code null}
|
||||||
* @param ch the underlying {@link SelectableChannel} on which it operates
|
* @param ch the underlying {@link SelectableChannel} on which it operates
|
||||||
*/
|
*/
|
||||||
protected AbstractNioByteChannel(Channel parent, EventLoop eventLoop, SelectableChannel ch) {
|
protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {
|
||||||
super(parent, eventLoop, ch, SelectionKey.OP_READ);
|
super(parent, ch, SelectionKey.OP_READ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -65,8 +65,8 @@ public abstract class AbstractNioChannel extends AbstractChannel {
|
|||||||
* @param ch the underlying {@link SelectableChannel} on which it operates
|
* @param ch the underlying {@link SelectableChannel} on which it operates
|
||||||
* @param readInterestOp the ops to set to receive data from the {@link SelectableChannel}
|
* @param readInterestOp the ops to set to receive data from the {@link SelectableChannel}
|
||||||
*/
|
*/
|
||||||
protected AbstractNioChannel(Channel parent, EventLoop eventLoop, SelectableChannel ch, int readInterestOp) {
|
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
|
||||||
super(parent, eventLoop);
|
super(parent);
|
||||||
this.ch = ch;
|
this.ch = ch;
|
||||||
this.readInterestOp = readInterestOp;
|
this.readInterestOp = readInterestOp;
|
||||||
try {
|
try {
|
||||||
|
@ -19,7 +19,6 @@ import io.netty.channel.Channel;
|
|||||||
import io.netty.channel.ChannelConfig;
|
import io.netty.channel.ChannelConfig;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.ServerChannel;
|
import io.netty.channel.ServerChannel;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -33,9 +32,11 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
|
public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
|
||||||
|
|
||||||
protected AbstractNioMessageChannel(
|
/**
|
||||||
Channel parent, EventLoop eventLoop, SelectableChannel ch, int readInterestOp) {
|
* @see {@link AbstractNioChannel#AbstractNioChannel(Channel, SelectableChannel, int)}
|
||||||
super(parent, eventLoop, ch, readInterestOp);
|
*/
|
||||||
|
protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
|
||||||
|
super(parent, ch, readInterestOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -169,5 +170,4 @@ public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
|
|||||||
* @return {@code true} if and only if the message has been written
|
* @return {@code true} if and only if the message has been written
|
||||||
*/
|
*/
|
||||||
protected abstract boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception;
|
protected abstract boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package io.netty.channel.nio;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.ServerChannel;
|
|
||||||
|
|
||||||
import java.nio.channels.SelectableChannel;
|
|
||||||
|
|
||||||
public abstract class AbstractNioMessageServerChannel extends AbstractNioMessageChannel implements ServerChannel {
|
|
||||||
|
|
||||||
private final EventLoopGroup childGroup;
|
|
||||||
|
|
||||||
protected AbstractNioMessageServerChannel(
|
|
||||||
Channel parent, EventLoop eventLoop, EventLoopGroup childGroup, SelectableChannel ch, int readInterestOp) {
|
|
||||||
super(parent, eventLoop, ch, readInterestOp);
|
|
||||||
this.childGroup = childGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EventLoopGroup childEventLoopGroup() {
|
|
||||||
return childGroup;
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,7 +22,6 @@ import io.netty.channel.ChannelMetadata;
|
|||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.FileRegion;
|
import io.netty.channel.FileRegion;
|
||||||
import io.netty.channel.socket.ChannelInputShutdownEvent;
|
import io.netty.channel.socket.ChannelInputShutdownEvent;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
@ -37,8 +36,11 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
|||||||
private volatile boolean inputShutdown;
|
private volatile boolean inputShutdown;
|
||||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||||
|
|
||||||
protected AbstractOioByteChannel(Channel parent, EventLoop eventLoop) {
|
/**
|
||||||
super(parent, eventLoop);
|
* @see AbstractOioByteChannel#AbstractOioByteChannel(Channel)
|
||||||
|
*/
|
||||||
|
protected AbstractOioByteChannel(Channel parent) {
|
||||||
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isInputShutdown() {
|
protected boolean isInputShutdown() {
|
||||||
|
@ -46,8 +46,11 @@ public abstract class AbstractOioChannel extends AbstractChannel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected AbstractOioChannel(Channel parent, EventLoop eventLoop) {
|
/**
|
||||||
super(parent, eventLoop);
|
* @see AbstractChannel#AbstractChannel(Channel)
|
||||||
|
*/
|
||||||
|
protected AbstractOioChannel(Channel parent) {
|
||||||
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,8 +18,6 @@ package io.netty.channel.oio;
|
|||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelConfig;
|
import io.netty.channel.ChannelConfig;
|
||||||
import io.netty.channel.ChannelPipeline;
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -31,8 +29,8 @@ public abstract class AbstractOioMessageChannel extends AbstractOioChannel {
|
|||||||
|
|
||||||
private final List<Object> readBuf = new ArrayList<Object>();
|
private final List<Object> readBuf = new ArrayList<Object>();
|
||||||
|
|
||||||
protected AbstractOioMessageChannel(Channel parent, EventLoop eventLoop) {
|
protected AbstractOioMessageChannel(Channel parent) {
|
||||||
super(parent, eventLoop);
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package io.netty.channel.oio;
|
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.ServerChannel;
|
|
||||||
|
|
||||||
public abstract class AbstractOioMessageServerChannel extends AbstractOioMessageChannel implements ServerChannel {
|
|
||||||
|
|
||||||
private final EventLoopGroup childGroup;
|
|
||||||
|
|
||||||
protected AbstractOioMessageServerChannel(Channel parent, EventLoop eventLoop, EventLoopGroup childGroup) {
|
|
||||||
super(parent, eventLoop);
|
|
||||||
this.childGroup = childGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EventLoopGroup childEventLoopGroup() {
|
|
||||||
return childGroup;
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,7 +17,6 @@ package io.netty.channel.oio;
|
|||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.FileRegion;
|
import io.netty.channel.FileRegion;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -57,8 +56,8 @@ public abstract class OioByteStreamChannel extends AbstractOioByteChannel {
|
|||||||
* @param parent the parent {@link Channel} which was used to create this instance. This can be null if the
|
* @param parent the parent {@link Channel} which was used to create this instance. This can be null if the
|
||||||
* {@link} has no parent as it was created by your self.
|
* {@link} has no parent as it was created by your self.
|
||||||
*/
|
*/
|
||||||
protected OioByteStreamChannel(Channel parent, EventLoop eventLoop) {
|
protected OioByteStreamChannel(Channel parent) {
|
||||||
super(parent, eventLoop);
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,6 @@ import io.netty.channel.ChannelMetadata;
|
|||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.RecvByteBufAllocator;
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||||
import io.netty.channel.socket.DatagramChannelConfig;
|
import io.netty.channel.socket.DatagramChannelConfig;
|
||||||
@ -106,40 +105,27 @@ public final class NioDatagramChannel
|
|||||||
/**
|
/**
|
||||||
* Create a new instance which will use the Operation Systems default {@link InternetProtocolFamily}.
|
* Create a new instance which will use the Operation Systems default {@link InternetProtocolFamily}.
|
||||||
*/
|
*/
|
||||||
public NioDatagramChannel(EventLoop eventLoop) {
|
public NioDatagramChannel() {
|
||||||
this(eventLoop, newSocket(DEFAULT_SELECTOR_PROVIDER));
|
this(newSocket(DEFAULT_SELECTOR_PROVIDER));
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance using the given {@link SelectorProvider}
|
|
||||||
* which will use the Operation Systems default {@link InternetProtocolFamily}.
|
|
||||||
*/
|
|
||||||
public NioDatagramChannel(EventLoop eventLoop, SelectorProvider provider) {
|
|
||||||
this(eventLoop, newSocket(provider));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance using the given {@link InternetProtocolFamily}. If {@code null} is used it will depend
|
* Create a new instance using the given {@link InternetProtocolFamily}. If {@code null} is used it will depend
|
||||||
* on the Operation Systems default which will be chosen.
|
* on the Operation Systems default which will be chosen.
|
||||||
*/
|
*/
|
||||||
public NioDatagramChannel(EventLoop eventLoop, InternetProtocolFamily ipFamily) {
|
public NioDatagramChannel(InternetProtocolFamily ipFamily) {
|
||||||
this(eventLoop, newSocket(DEFAULT_SELECTOR_PROVIDER, ipFamily));
|
this(DEFAULT_SELECTOR_PROVIDER, ipFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public NioDatagramChannel(SelectorProvider provider, InternetProtocolFamily ipFamily) {
|
||||||
* Create a new instance using the given {@link SelectorProvider} and {@link InternetProtocolFamily}.
|
this(newSocket(provider, ipFamily));
|
||||||
* If {@link InternetProtocolFamily} is {@code null} it will depend on the Operation Systems default
|
|
||||||
* which will be chosen.
|
|
||||||
*/
|
|
||||||
public NioDatagramChannel(EventLoop eventLoop, SelectorProvider provider, InternetProtocolFamily ipFamily) {
|
|
||||||
this(eventLoop, newSocket(provider, ipFamily));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance from the given {@link DatagramChannel}.
|
* Create a new instance from the given {@link DatagramChannel}.
|
||||||
*/
|
*/
|
||||||
public NioDatagramChannel(EventLoop eventLoop, DatagramChannel socket) {
|
public NioDatagramChannel(DatagramChannel socket) {
|
||||||
super(null, eventLoop, socket, SelectionKey.OP_READ);
|
super(null, socket, SelectionKey.OP_READ);
|
||||||
config = new NioDatagramChannelConfig(this, socket);
|
config = new NioDatagramChannelConfig(this, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,9 +18,7 @@ package io.netty.channel.socket.nio;
|
|||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.nio.AbstractNioMessageServerChannel;
|
|
||||||
import io.netty.channel.socket.DefaultServerSocketChannelConfig;
|
import io.netty.channel.socket.DefaultServerSocketChannelConfig;
|
||||||
import io.netty.channel.socket.ServerSocketChannelConfig;
|
import io.netty.channel.socket.ServerSocketChannelConfig;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
@ -40,7 +38,7 @@ import java.util.List;
|
|||||||
* A {@link io.netty.channel.socket.ServerSocketChannel} implementation which uses
|
* A {@link io.netty.channel.socket.ServerSocketChannel} implementation which uses
|
||||||
* NIO selector based implementation to accept new connections.
|
* NIO selector based implementation to accept new connections.
|
||||||
*/
|
*/
|
||||||
public class NioServerSocketChannel extends AbstractNioMessageServerChannel
|
public class NioServerSocketChannel extends AbstractNioMessageChannel
|
||||||
implements io.netty.channel.socket.ServerSocketChannel {
|
implements io.netty.channel.socket.ServerSocketChannel {
|
||||||
|
|
||||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||||
@ -68,22 +66,12 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel
|
|||||||
/**
|
/**
|
||||||
* Create a new instance
|
* Create a new instance
|
||||||
*/
|
*/
|
||||||
public NioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
public NioServerSocketChannel() {
|
||||||
this(eventLoop, childGroup, newSocket(DEFAULT_SELECTOR_PROVIDER));
|
this(DEFAULT_SELECTOR_PROVIDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public NioServerSocketChannel(SelectorProvider provider) {
|
||||||
* Create a new instance using the given {@link SelectorProvider}.
|
super(null, newSocket(provider), SelectionKey.OP_ACCEPT);
|
||||||
*/
|
|
||||||
public NioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup, SelectorProvider provider) {
|
|
||||||
this(eventLoop, childGroup, newSocket(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new instance using the given {@link ServerSocketChannel}.
|
|
||||||
*/
|
|
||||||
public NioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup, ServerSocketChannel channel) {
|
|
||||||
super(null, eventLoop, childGroup, channel, SelectionKey.OP_ACCEPT);
|
|
||||||
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
|
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +126,7 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (ch != null) {
|
if (ch != null) {
|
||||||
buf.add(new NioSocketChannel(this, childEventLoopGroup().next(), ch));
|
buf.add(new NioSocketChannel(this, ch));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -66,32 +66,31 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
|
|||||||
/**
|
/**
|
||||||
* Create a new instance
|
* Create a new instance
|
||||||
*/
|
*/
|
||||||
public NioSocketChannel(EventLoop eventLoop) {
|
public NioSocketChannel() {
|
||||||
this(eventLoop, newSocket(DEFAULT_SELECTOR_PROVIDER));
|
this(DEFAULT_SELECTOR_PROVIDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance using the given {@link SelectorProvider}.
|
* Create a new instance using the given {@link SelectorProvider}.
|
||||||
*/
|
*/
|
||||||
public NioSocketChannel(EventLoop eventLoop, SelectorProvider provider) {
|
public NioSocketChannel(SelectorProvider provider) {
|
||||||
this(eventLoop, newSocket(provider));
|
this(newSocket(provider));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance using the given {@link SocketChannel}.
|
* Create a new instance using the given {@link SocketChannel}.
|
||||||
*/
|
*/
|
||||||
public NioSocketChannel(EventLoop eventLoop, SocketChannel socket) {
|
public NioSocketChannel(SocketChannel socket) {
|
||||||
this(null, eventLoop, socket);
|
this(null, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance
|
* Create a new instance
|
||||||
*
|
*
|
||||||
* @param parent the {@link Channel} which created this instance or {@code null} if it was created by the user
|
* @param parent the {@link Channel} which created this instance or {@code null} if it was created by the user
|
||||||
* @param socket the {@link SocketChannel} which will be used
|
* @param socket the {@link SocketChannel} which will be used
|
||||||
*/
|
*/
|
||||||
public NioSocketChannel(Channel parent, EventLoop eventLoop, SocketChannel socket) {
|
public NioSocketChannel(Channel parent, SocketChannel socket) {
|
||||||
super(parent, eventLoop, socket);
|
super(parent, socket);
|
||||||
config = new NioSocketChannelConfig(this, socket.socket());
|
config = new NioSocketChannelConfig(this, socket.socket());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ import io.netty.channel.ChannelMetadata;
|
|||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.channel.EventLoop;
|
|
||||||
import io.netty.channel.RecvByteBufAllocator;
|
import io.netty.channel.RecvByteBufAllocator;
|
||||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||||
import io.netty.channel.socket.DatagramChannel;
|
import io.netty.channel.socket.DatagramChannel;
|
||||||
@ -56,7 +55,8 @@ import java.util.Locale;
|
|||||||
* @see AddressedEnvelope
|
* @see AddressedEnvelope
|
||||||
* @see DatagramPacket
|
* @see DatagramPacket
|
||||||
*/
|
*/
|
||||||
public final class OioDatagramChannel extends AbstractOioMessageChannel implements DatagramChannel {
|
public class OioDatagramChannel extends AbstractOioMessageChannel
|
||||||
|
implements DatagramChannel {
|
||||||
|
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(OioDatagramChannel.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(OioDatagramChannel.class);
|
||||||
|
|
||||||
@ -79,8 +79,8 @@ public final class OioDatagramChannel extends AbstractOioMessageChannel implemen
|
|||||||
/**
|
/**
|
||||||
* Create a new instance with an new {@link MulticastSocket}.
|
* Create a new instance with an new {@link MulticastSocket}.
|
||||||
*/
|
*/
|
||||||
public OioDatagramChannel(EventLoop eventLoop) {
|
public OioDatagramChannel() {
|
||||||
this(eventLoop, newSocket());
|
this(newSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,8 +88,8 @@ public final class OioDatagramChannel extends AbstractOioMessageChannel implemen
|
|||||||
*
|
*
|
||||||
* @param socket the {@link MulticastSocket} which is used by this instance
|
* @param socket the {@link MulticastSocket} which is used by this instance
|
||||||
*/
|
*/
|
||||||
public OioDatagramChannel(EventLoop eventLoop, MulticastSocket socket) {
|
public OioDatagramChannel(MulticastSocket socket) {
|
||||||
super(null, eventLoop);
|
super(null);
|
||||||
|
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
|
@ -18,9 +18,7 @@ package io.netty.channel.socket.oio;
|
|||||||
import io.netty.channel.ChannelException;
|
import io.netty.channel.ChannelException;
|
||||||
import io.netty.channel.ChannelMetadata;
|
import io.netty.channel.ChannelMetadata;
|
||||||
import io.netty.channel.ChannelOutboundBuffer;
|
import io.netty.channel.ChannelOutboundBuffer;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||||
import io.netty.channel.EventLoopGroup;
|
|
||||||
import io.netty.channel.oio.AbstractOioMessageServerChannel;
|
|
||||||
import io.netty.channel.socket.ServerSocketChannel;
|
import io.netty.channel.socket.ServerSocketChannel;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
@ -40,7 +38,8 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
*
|
*
|
||||||
* This implementation use Old-Blocking-IO.
|
* This implementation use Old-Blocking-IO.
|
||||||
*/
|
*/
|
||||||
public class OioServerSocketChannel extends AbstractOioMessageServerChannel implements ServerSocketChannel {
|
public class OioServerSocketChannel extends AbstractOioMessageChannel
|
||||||
|
implements ServerSocketChannel {
|
||||||
|
|
||||||
private static final InternalLogger logger =
|
private static final InternalLogger logger =
|
||||||
InternalLoggerFactory.getInstance(OioServerSocketChannel.class);
|
InternalLoggerFactory.getInstance(OioServerSocketChannel.class);
|
||||||
@ -62,8 +61,8 @@ public class OioServerSocketChannel extends AbstractOioMessageServerChannel impl
|
|||||||
/**
|
/**
|
||||||
* Create a new instance with an new {@link Socket}
|
* Create a new instance with an new {@link Socket}
|
||||||
*/
|
*/
|
||||||
public OioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
public OioServerSocketChannel() {
|
||||||
this(eventLoop, childGroup, newServerSocket());
|
this(newServerSocket());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -71,8 +70,8 @@ public class OioServerSocketChannel extends AbstractOioMessageServerChannel impl
|
|||||||
*
|
*
|
||||||
* @param socket the {@link ServerSocket} which is used by this instance
|
* @param socket the {@link ServerSocket} which is used by this instance
|
||||||
*/
|
*/
|
||||||
public OioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup, ServerSocket socket) {
|
public OioServerSocketChannel(ServerSocket socket) {
|
||||||
super(null, eventLoop, childGroup);
|
super(null);
|
||||||
if (socket == null) {
|
if (socket == null) {
|
||||||
throw new NullPointerException("socket");
|
throw new NullPointerException("socket");
|
||||||
}
|
}
|
||||||
@ -155,7 +154,7 @@ public class OioServerSocketChannel extends AbstractOioMessageServerChannel impl
|
|||||||
Socket s = socket.accept();
|
Socket s = socket.accept();
|
||||||
try {
|
try {
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
buf.add(new OioSocketChannel(this, childEventLoopGroup().next(), s));
|
buf.add(new OioSocketChannel(this, s));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -49,8 +49,8 @@ public class OioSocketChannel extends OioByteStreamChannel
|
|||||||
/**
|
/**
|
||||||
* Create a new instance with an new {@link Socket}
|
* Create a new instance with an new {@link Socket}
|
||||||
*/
|
*/
|
||||||
public OioSocketChannel(EventLoop eventLoop) {
|
public OioSocketChannel() {
|
||||||
this(eventLoop, new Socket());
|
this(new Socket());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,8 +58,8 @@ public class OioSocketChannel extends OioByteStreamChannel
|
|||||||
*
|
*
|
||||||
* @param socket the {@link Socket} which is used by this instance
|
* @param socket the {@link Socket} which is used by this instance
|
||||||
*/
|
*/
|
||||||
public OioSocketChannel(EventLoop eventLoop, Socket socket) {
|
public OioSocketChannel(Socket socket) {
|
||||||
this(null, eventLoop, socket);
|
this(null, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,8 +69,8 @@ public class OioSocketChannel extends OioByteStreamChannel
|
|||||||
* {@link} has no parent as it was created by your self.
|
* {@link} has no parent as it was created by your self.
|
||||||
* @param socket the {@link Socket} which is used by this instance
|
* @param socket the {@link Socket} which is used by this instance
|
||||||
*/
|
*/
|
||||||
public OioSocketChannel(Channel parent, EventLoop eventLoop, Socket socket) {
|
public OioSocketChannel(Channel parent, Socket socket) {
|
||||||
super(parent, eventLoop);
|
super(parent);
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
config = new DefaultOioSocketChannelConfig(this, socket);
|
config = new DefaultOioSocketChannelConfig(this, socket);
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveChannelHandler() {
|
public void testRemoveChannelHandler() {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
|
||||||
ChannelHandler handler1 = newHandler();
|
ChannelHandler handler1 = newHandler();
|
||||||
ChannelHandler handler2 = newHandler();
|
ChannelHandler handler2 = newHandler();
|
||||||
@ -160,7 +160,7 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReplaceChannelHandler() {
|
public void testReplaceChannelHandler() {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
|
||||||
ChannelHandler handler1 = newHandler();
|
ChannelHandler handler1 = newHandler();
|
||||||
pipeline.addLast("handler1", handler1);
|
pipeline.addLast("handler1", handler1);
|
||||||
@ -185,7 +185,7 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChannelHandlerContextNavigation() {
|
public void testChannelHandlerContextNavigation() {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
|
||||||
final int HANDLER_ARRAY_LEN = 5;
|
final int HANDLER_ARRAY_LEN = 5;
|
||||||
ChannelHandler[] firstHandlers = newHandlers(HANDLER_ARRAY_LEN);
|
ChannelHandler[] firstHandlers = newHandlers(HANDLER_ARRAY_LEN);
|
||||||
@ -200,12 +200,11 @@ public class DefaultChannelPipelineTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testFireChannelRegistered() throws Exception {
|
public void testFireChannelRegistered() throws Exception {
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
Channel ch = new LocalChannel(group.next());
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
ChannelPipeline pipeline = ch.pipeline();
|
|
||||||
pipeline.addLast(new ChannelInitializer<Channel>() {
|
pipeline.addLast(new ChannelInitializer<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(Channel ch) throws Exception {
|
protected void initChannel(Channel ch) throws Exception {
|
||||||
ch.pipeline().addLast(new ChannelHandlerAdapter() {
|
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
|
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
@ -213,13 +212,13 @@ public class DefaultChannelPipelineTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ch.unsafe().register(ch.newPromise());
|
group.register(pipeline.channel());
|
||||||
assertTrue(latch.await(2, TimeUnit.SECONDS));
|
assertTrue(latch.await(2, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPipelineOperation() {
|
public void testPipelineOperation() {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
|
||||||
final int handlerNum = 5;
|
final int handlerNum = 5;
|
||||||
ChannelHandler[] handlers1 = newHandlers(handlerNum);
|
ChannelHandler[] handlers1 = newHandlers(handlerNum);
|
||||||
@ -247,7 +246,7 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChannelHandlerContextOrder() {
|
public void testChannelHandlerContextOrder() {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
|
||||||
pipeline.addFirst("1", newHandler());
|
pipeline.addFirst("1", newHandler());
|
||||||
pipeline.addLast("10", newHandler());
|
pipeline.addLast("10", newHandler());
|
||||||
@ -444,7 +443,8 @@ public class DefaultChannelPipelineTest {
|
|||||||
// Tests for https://github.com/netty/netty/issues/2349
|
// Tests for https://github.com/netty/netty/issues/2349
|
||||||
@Test
|
@Test
|
||||||
public void testCancelBind() throws Exception {
|
public void testCancelBind() throws Exception {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
group.register(pipeline.channel());
|
||||||
|
|
||||||
ChannelPromise promise = pipeline.channel().newPromise();
|
ChannelPromise promise = pipeline.channel().newPromise();
|
||||||
assertTrue(promise.cancel(false));
|
assertTrue(promise.cancel(false));
|
||||||
@ -454,7 +454,8 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCancelConnect() throws Exception {
|
public void testCancelConnect() throws Exception {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
group.register(pipeline.channel());
|
||||||
|
|
||||||
ChannelPromise promise = pipeline.channel().newPromise();
|
ChannelPromise promise = pipeline.channel().newPromise();
|
||||||
assertTrue(promise.cancel(false));
|
assertTrue(promise.cancel(false));
|
||||||
@ -464,7 +465,8 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCancelDisconnect() throws Exception {
|
public void testCancelDisconnect() throws Exception {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
group.register(pipeline.channel());
|
||||||
|
|
||||||
ChannelPromise promise = pipeline.channel().newPromise();
|
ChannelPromise promise = pipeline.channel().newPromise();
|
||||||
assertTrue(promise.cancel(false));
|
assertTrue(promise.cancel(false));
|
||||||
@ -474,7 +476,8 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCancelClose() throws Exception {
|
public void testCancelClose() throws Exception {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
group.register(pipeline.channel());
|
||||||
|
|
||||||
ChannelPromise promise = pipeline.channel().newPromise();
|
ChannelPromise promise = pipeline.channel().newPromise();
|
||||||
assertTrue(promise.cancel(false));
|
assertTrue(promise.cancel(false));
|
||||||
@ -482,9 +485,21 @@ public class DefaultChannelPipelineTest {
|
|||||||
assertTrue(future.isCancelled());
|
assertTrue(future.isCancelled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCancelDeregister() throws Exception {
|
||||||
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
group.register(pipeline.channel());
|
||||||
|
|
||||||
|
ChannelPromise promise = pipeline.channel().newPromise();
|
||||||
|
assertTrue(promise.cancel(false));
|
||||||
|
ChannelFuture future = pipeline.deregister(promise);
|
||||||
|
assertTrue(future.isCancelled());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCancelWrite() throws Exception {
|
public void testCancelWrite() throws Exception {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
group.register(pipeline.channel());
|
||||||
|
|
||||||
ChannelPromise promise = pipeline.channel().newPromise();
|
ChannelPromise promise = pipeline.channel().newPromise();
|
||||||
assertTrue(promise.cancel(false));
|
assertTrue(promise.cancel(false));
|
||||||
@ -497,7 +512,8 @@ public class DefaultChannelPipelineTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCancelWriteAndFlush() throws Exception {
|
public void testCancelWriteAndFlush() throws Exception {
|
||||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||||
|
group.register(pipeline.channel());
|
||||||
|
|
||||||
ChannelPromise promise = pipeline.channel().newPromise();
|
ChannelPromise promise = pipeline.channel().newPromise();
|
||||||
assertTrue(promise.cancel(false));
|
assertTrue(promise.cancel(false));
|
||||||
|
@ -22,8 +22,8 @@ import java.util.EnumSet;
|
|||||||
final class LoggingHandler implements ChannelHandler {
|
final class LoggingHandler implements ChannelHandler {
|
||||||
|
|
||||||
enum Event {
|
enum Event {
|
||||||
WRITE, FLUSH, BIND, CONNECT, DISCONNECT, CLOSE, READ, WRITABILITY, HANDLER_ADDED,
|
WRITE, FLUSH, BIND, CONNECT, DISCONNECT, CLOSE, DEREGISTER, READ, WRITABILITY, HANDLER_ADDED,
|
||||||
HANDLER_REMOVED, EXCEPTION, READ_COMPLETE, REGISTERED, ACTIVE, INACTIVE, USER
|
HANDLER_REMOVED, EXCEPTION, READ_COMPLETE, REGISTERED, UNREGISTERED, ACTIVE, INACTIVE, USER
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuilder log = new StringBuilder();
|
private StringBuilder log = new StringBuilder();
|
||||||
@ -68,6 +68,12 @@ final class LoggingHandler implements ChannelHandler {
|
|||||||
ctx.close(promise);
|
ctx.close(promise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
|
||||||
|
log(Event.DEREGISTER);
|
||||||
|
ctx.deregister(promise);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ChannelHandlerContext ctx) throws Exception {
|
public void read(ChannelHandlerContext ctx) throws Exception {
|
||||||
log(Event.READ);
|
log(Event.READ);
|
||||||
@ -101,6 +107,12 @@ final class LoggingHandler implements ChannelHandler {
|
|||||||
ctx.fireChannelRegistered();
|
ctx.fireChannelRegistered();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
|
||||||
|
log(Event.UNREGISTERED);
|
||||||
|
ctx.fireChannelUnregistered();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||||
log(Event.ACTIVE);
|
log(Event.ACTIVE);
|
||||||
|
@ -339,13 +339,11 @@ public class SingleThreadEventLoopTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Channel channel = new LocalChannel(loopA);
|
ChannelFuture f = loopA.register(new LocalChannel());
|
||||||
ChannelPromise f = channel.newPromise();
|
|
||||||
channel.unsafe().register(f);
|
|
||||||
f.awaitUninterruptibly();
|
f.awaitUninterruptibly();
|
||||||
assertFalse(f.isSuccess());
|
assertFalse(f.isSuccess());
|
||||||
assertThat(f.cause(), is(instanceOf(RejectedExecutionException.class)));
|
assertThat(f.cause(), is(instanceOf(RejectedExecutionException.class)));
|
||||||
assertFalse(channel.isOpen());
|
assertFalse(f.channel().isOpen());
|
||||||
} finally {
|
} finally {
|
||||||
for (Appender<ILoggingEvent> a: appenders) {
|
for (Appender<ILoggingEvent> a: appenders) {
|
||||||
root.addAppender(a);
|
root.addAppender(a);
|
||||||
@ -358,7 +356,7 @@ public class SingleThreadEventLoopTest {
|
|||||||
public void testRegistrationAfterShutdown2() throws Exception {
|
public void testRegistrationAfterShutdown2() throws Exception {
|
||||||
loopA.shutdown();
|
loopA.shutdown();
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
Channel ch = new LocalChannel(loopA);
|
Channel ch = new LocalChannel();
|
||||||
ChannelPromise promise = ch.newPromise();
|
ChannelPromise promise = ch.newPromise();
|
||||||
promise.addListener(new ChannelFutureListener() {
|
promise.addListener(new ChannelFutureListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -377,10 +375,10 @@ public class SingleThreadEventLoopTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ch.unsafe().register(promise);
|
ChannelFuture f = loopA.register(ch, promise);
|
||||||
promise.awaitUninterruptibly();
|
f.awaitUninterruptibly();
|
||||||
assertFalse(promise.isSuccess());
|
assertFalse(f.isSuccess());
|
||||||
assertThat(promise.cause(), is(instanceOf(RejectedExecutionException.class)));
|
assertThat(f.cause(), is(instanceOf(RejectedExecutionException.class)));
|
||||||
|
|
||||||
// Ensure the listener was notified.
|
// Ensure the listener was notified.
|
||||||
assertFalse(latch.await(1, TimeUnit.SECONDS));
|
assertFalse(latch.await(1, TimeUnit.SECONDS));
|
||||||
|
@ -82,7 +82,7 @@ public class ThreadPerChannelEventLoopGroupTest {
|
|||||||
ChannelGroup channelGroup = new DefaultChannelGroup(testExecutor);
|
ChannelGroup channelGroup = new DefaultChannelGroup(testExecutor);
|
||||||
while (taskCount-- > 0) {
|
while (taskCount-- > 0) {
|
||||||
Channel channel = new EmbeddedChannel(NOOP_HANDLER);
|
Channel channel = new EmbeddedChannel(NOOP_HANDLER);
|
||||||
channel.unsafe().register(new DefaultChannelPromise(channel, testExecutor));
|
loopGroup.register(channel, new DefaultChannelPromise(channel, testExecutor));
|
||||||
channelGroup.add(channel);
|
channelGroup.add(channel);
|
||||||
}
|
}
|
||||||
channelGroup.close().sync();
|
channelGroup.close().sync();
|
||||||
|
@ -89,7 +89,7 @@ public class LocalTransportThreadModelTest {
|
|||||||
ThreadNameAuditor h2 = new ThreadNameAuditor();
|
ThreadNameAuditor h2 = new ThreadNameAuditor();
|
||||||
ThreadNameAuditor h3 = new ThreadNameAuditor(true);
|
ThreadNameAuditor h3 = new ThreadNameAuditor(true);
|
||||||
|
|
||||||
Channel ch = new LocalChannel(l.next());
|
Channel ch = new LocalChannel();
|
||||||
// With no EventExecutor specified, h1 will be always invoked by EventLoop 'l'.
|
// With no EventExecutor specified, h1 will be always invoked by EventLoop 'l'.
|
||||||
ch.pipeline().addLast(h1);
|
ch.pipeline().addLast(h1);
|
||||||
// h2 will be always invoked by EventExecutor 'e1'.
|
// h2 will be always invoked by EventExecutor 'e1'.
|
||||||
@ -97,9 +97,7 @@ public class LocalTransportThreadModelTest {
|
|||||||
// h3 will be always invoked by EventExecutor 'e2'.
|
// h3 will be always invoked by EventExecutor 'e2'.
|
||||||
ch.pipeline().addLast(e2, h3);
|
ch.pipeline().addLast(e2, h3);
|
||||||
|
|
||||||
ChannelPromise promise = ch.newPromise();
|
l.register(ch).sync().channel().connect(localAddr).sync();
|
||||||
ch.unsafe().register(promise);
|
|
||||||
promise.sync().channel().connect(localAddr).sync();
|
|
||||||
|
|
||||||
// Fire inbound events from all possible starting points.
|
// Fire inbound events from all possible starting points.
|
||||||
ch.pipeline().fireChannelRead("1");
|
ch.pipeline().fireChannelRead("1");
|
||||||
@ -242,7 +240,7 @@ public class LocalTransportThreadModelTest {
|
|||||||
final MessageForwarder2 h5 = new MessageForwarder2();
|
final MessageForwarder2 h5 = new MessageForwarder2();
|
||||||
final MessageDiscarder h6 = new MessageDiscarder();
|
final MessageDiscarder h6 = new MessageDiscarder();
|
||||||
|
|
||||||
final Channel ch = new LocalChannel(l.next());
|
final Channel ch = new LocalChannel();
|
||||||
|
|
||||||
// inbound: int -> byte[4] -> int -> int -> byte[4] -> int -> /dev/null
|
// inbound: int -> byte[4] -> int -> int -> byte[4] -> int -> /dev/null
|
||||||
// outbound: int -> int -> byte[4] -> int -> int -> byte[4] -> /dev/null
|
// outbound: int -> int -> byte[4] -> int -> int -> byte[4] -> /dev/null
|
||||||
@ -253,9 +251,7 @@ public class LocalTransportThreadModelTest {
|
|||||||
.addLast(e4, h5)
|
.addLast(e4, h5)
|
||||||
.addLast(e5, h6);
|
.addLast(e5, h6);
|
||||||
|
|
||||||
ChannelPromise promise = ch.newPromise();
|
l.register(ch).sync().channel().connect(localAddr).sync();
|
||||||
ch.unsafe().register(promise);
|
|
||||||
promise.sync().channel().connect(localAddr).sync();
|
|
||||||
|
|
||||||
final int ROUNDS = 1024;
|
final int ROUNDS = 1024;
|
||||||
final int ELEMS_PER_ROUNDS = 8192;
|
final int ELEMS_PER_ROUNDS = 8192;
|
||||||
|
@ -130,7 +130,7 @@ public class LocalTransportThreadModelTest3 {
|
|||||||
final EventForwarder h5 = new EventForwarder();
|
final EventForwarder h5 = new EventForwarder();
|
||||||
final EventRecorder h6 = new EventRecorder(events, inbound);
|
final EventRecorder h6 = new EventRecorder(events, inbound);
|
||||||
|
|
||||||
final Channel ch = new LocalChannel(l.next());
|
final Channel ch = new LocalChannel();
|
||||||
if (!inbound) {
|
if (!inbound) {
|
||||||
ch.config().setAutoRead(false);
|
ch.config().setAutoRead(false);
|
||||||
}
|
}
|
||||||
@ -141,9 +141,7 @@ public class LocalTransportThreadModelTest3 {
|
|||||||
.addLast(e1, h5)
|
.addLast(e1, h5)
|
||||||
.addLast(e1, "recorder", h6);
|
.addLast(e1, "recorder", h6);
|
||||||
|
|
||||||
ChannelPromise promise = ch.newPromise();
|
l.register(ch).sync().channel().connect(localAddr).sync();
|
||||||
ch.unsafe().register(promise);
|
|
||||||
promise.sync().channel().connect(localAddr).sync();
|
|
||||||
|
|
||||||
final LinkedList<EventType> expectedEvents = events(inbound, 8192);
|
final LinkedList<EventType> expectedEvents = events(inbound, 8192);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user