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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
|
||||
if (logger.isEnabled(internalLevel)) {
|
||||
logger.log(internalLevel, format(ctx, "UNREGISTERED"));
|
||||
}
|
||||
ctx.fireChannelUnregistered();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
if (logger.isEnabled(internalLevel)) {
|
||||
|
@ -21,7 +21,6 @@ import io.netty.bootstrap.ChannelFactory;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.oio.OioEventLoopGroup;
|
||||
@ -109,8 +108,8 @@ public class SocketTestPermutation {
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
|
||||
@Override
|
||||
public Channel newChannel(EventLoop loop) {
|
||||
return new NioDatagramChannel(loop, InternetProtocolFamily.IPv4);
|
||||
public Channel newChannel() {
|
||||
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,12 +32,12 @@ abstract class AbstractEpollChannel extends AbstractChannel {
|
||||
volatile int fd;
|
||||
int id;
|
||||
|
||||
AbstractEpollChannel(EventLoop eventLoop, int fd, int flag) {
|
||||
this(null, eventLoop, fd, flag, false);
|
||||
AbstractEpollChannel(int fd, int flag) {
|
||||
this(null, fd, flag, false);
|
||||
}
|
||||
|
||||
AbstractEpollChannel(Channel parent, EventLoop eventLoop, int fd, int flag, boolean active) {
|
||||
super(parent, eventLoop);
|
||||
AbstractEpollChannel(Channel parent, int fd, int flag, boolean active) {
|
||||
super(parent);
|
||||
this.fd = fd;
|
||||
readFlag = flag;
|
||||
flags |= flag;
|
||||
|
@ -23,7 +23,6 @@ import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.socket.DatagramChannel;
|
||||
import io.netty.channel.socket.DatagramChannelConfig;
|
||||
@ -51,8 +50,8 @@ public final class EpollDatagramChannel extends AbstractEpollChannel implements
|
||||
private volatile boolean connected;
|
||||
private final EpollDatagramChannelConfig config;
|
||||
|
||||
public EpollDatagramChannel(EventLoop loop) {
|
||||
super(loop, Native.socketDgramFd(), Native.EPOLLIN);
|
||||
public EpollDatagramChannel() {
|
||||
super(Native.socketDgramFd(), Native.EPOLLIN);
|
||||
config = new EpollDatagramChannelConfig(this);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,6 @@ import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.socket.ServerSocketChannel;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
@ -32,13 +31,11 @@ import java.net.SocketAddress;
|
||||
public final class EpollServerSocketChannel extends AbstractEpollChannel implements ServerSocketChannel {
|
||||
|
||||
private final EpollServerSocketChannelConfig config;
|
||||
private final EventLoopGroup childGroup;
|
||||
private volatile InetSocketAddress local;
|
||||
|
||||
public EpollServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
super(eventLoop, Native.socketStreamFd(), Native.EPOLLACCEPT);
|
||||
public EpollServerSocketChannel() {
|
||||
super(Native.socketStreamFd(), Native.EPOLLACCEPT);
|
||||
config = new EpollServerSocketChannelConfig(this);
|
||||
this.childGroup = childGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -81,11 +78,6 @@ public final class EpollServerSocketChannel extends AbstractEpollChannel impleme
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventLoopGroup childEventLoopGroup() {
|
||||
return childGroup;
|
||||
}
|
||||
|
||||
final class EpollServerSocketUnsafe extends AbstractEpollUnsafe {
|
||||
|
||||
@Override
|
||||
@ -109,8 +101,7 @@ public final class EpollServerSocketChannel extends AbstractEpollChannel impleme
|
||||
}
|
||||
try {
|
||||
readPending = false;
|
||||
pipeline.fireChannelRead(new EpollSocketChannel(EpollServerSocketChannel.this,
|
||||
childEventLoopGroup().next(), socketFd));
|
||||
pipeline.fireChannelRead(new EpollSocketChannel(EpollServerSocketChannel.this, socketFd));
|
||||
} catch (Throwable t) {
|
||||
// keep on reading as we use epoll ET and need to consume everything from the socket
|
||||
pipeline.fireChannelReadComplete();
|
||||
|
@ -66,8 +66,8 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
|
||||
private volatile boolean inputShutdown;
|
||||
private volatile boolean outputShutdown;
|
||||
|
||||
EpollSocketChannel(Channel parent, EventLoop eventLoop, int fd) {
|
||||
super(parent, eventLoop, fd, Native.EPOLLIN, true);
|
||||
EpollSocketChannel(Channel parent, int fd) {
|
||||
super(parent, fd, Native.EPOLLIN, true);
|
||||
config = new EpollSocketChannelConfig(this);
|
||||
// Directly cache the remote and local addresses
|
||||
// See https://github.com/netty/netty/issues/2359
|
||||
@ -75,8 +75,8 @@ public final class EpollSocketChannel extends AbstractEpollChannel implements So
|
||||
local = Native.localAddress(fd);
|
||||
}
|
||||
|
||||
public EpollSocketChannel(EventLoop eventLoop) {
|
||||
super(eventLoop, Native.socketStreamFd(), Native.EPOLLIN);
|
||||
public EpollSocketChannel() {
|
||||
super(Native.socketStreamFd(), Native.EPOLLIN);
|
||||
config = new EpollSocketChannelConfig(this);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,6 @@ import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.bootstrap.ChannelFactory;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.socket.InternetProtocolFamily;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
@ -100,8 +99,8 @@ class EpollSocketTestPermutation extends SocketTestPermutation {
|
||||
public Bootstrap newInstance() {
|
||||
return new Bootstrap().group(nioWorkerGroup).channelFactory(new ChannelFactory<Channel>() {
|
||||
@Override
|
||||
public Channel newChannel(EventLoop loop) {
|
||||
return new NioDatagramChannel(loop, InternetProtocolFamily.IPv4);
|
||||
public Channel newChannel() {
|
||||
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,6 @@ import gnu.io.CommPort;
|
||||
import gnu.io.CommPortIdentifier;
|
||||
import gnu.io.SerialPort;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.oio.OioByteStreamChannel;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
@ -40,8 +39,8 @@ public class RxtxChannel extends OioByteStreamChannel {
|
||||
private RxtxDeviceAddress deviceAddress;
|
||||
private SerialPort serialPort;
|
||||
|
||||
public RxtxChannel(EventLoop eventLoop) {
|
||||
super(null, eventLoop);
|
||||
public RxtxChannel() {
|
||||
super(null);
|
||||
|
||||
config = new DefaultRxtxChannelConfig(this);
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
||||
@ -82,15 +81,15 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett
|
||||
/**
|
||||
* Create a new instance
|
||||
*/
|
||||
public NioSctpChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, newSctpChannel());
|
||||
public NioSctpChannel() {
|
||||
this(newSctpChannel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance using {@link SctpChannel}
|
||||
*/
|
||||
public NioSctpChannel(EventLoop eventLoop, SctpChannel sctpChannel) {
|
||||
this(null, eventLoop, sctpChannel);
|
||||
public NioSctpChannel(SctpChannel sctpChannel) {
|
||||
this(null, sctpChannel);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,8 +99,8 @@ public class NioSctpChannel extends AbstractNioMessageChannel implements io.nett
|
||||
* or {@code null}.
|
||||
* @param sctpChannel the underlying {@link SctpChannel}
|
||||
*/
|
||||
public NioSctpChannel(Channel parent, EventLoop eventLoop, SctpChannel sctpChannel) {
|
||||
super(parent, eventLoop, sctpChannel, SelectionKey.OP_READ);
|
||||
public NioSctpChannel(Channel parent, SctpChannel sctpChannel) {
|
||||
super(parent, sctpChannel, SelectionKey.OP_READ);
|
||||
try {
|
||||
sctpChannel.configureBlocking(false);
|
||||
config = new NioSctpChannelConfig(this, sctpChannel);
|
||||
|
@ -22,9 +22,7 @@ import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.AbstractNioMessageServerChannel;
|
||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||
import io.netty.channel.sctp.DefaultSctpServerChannelConfig;
|
||||
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,
|
||||
* 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 {
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||
|
||||
private static SctpServerChannel newSocket() {
|
||||
@ -65,9 +62,9 @@ public class NioSctpServerChannel extends AbstractNioMessageServerChannel
|
||||
/**
|
||||
* Create a new instance
|
||||
*/
|
||||
public NioSctpServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
super(null, eventLoop, childGroup, newSocket(), SelectionKey.OP_ACCEPT);
|
||||
config = new NioSctpServerChannelConfig(this, javaChannel());
|
||||
public NioSctpServerChannel() {
|
||||
super(null, newSocket(), SelectionKey.OP_ACCEPT);
|
||||
config = new DefaultSctpServerChannelConfig(this, javaChannel());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -143,7 +140,7 @@ public class NioSctpServerChannel extends AbstractNioMessageServerChannel
|
||||
if (ch == null) {
|
||||
return 0;
|
||||
}
|
||||
buf.add(new NioSctpChannel(this, childEventLoopGroup().next(), ch));
|
||||
buf.add(new NioSctpChannel(this, ch));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||
import io.netty.channel.sctp.DefaultSctpChannelConfig;
|
||||
@ -88,8 +87,8 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
||||
/**
|
||||
* Create a new instance with an new {@link SctpChannel}.
|
||||
*/
|
||||
public OioSctpChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, openChannel());
|
||||
public OioSctpChannel() {
|
||||
this(openChannel());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,8 +96,8 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
||||
*
|
||||
* @param ch the {@link SctpChannel} which is used by this instance
|
||||
*/
|
||||
public OioSctpChannel(EventLoop eventLoop, SctpChannel ch) {
|
||||
this(null, eventLoop, ch);
|
||||
public OioSctpChannel(SctpChannel ch) {
|
||||
this(null, ch);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,8 +107,8 @@ public class OioSctpChannel extends AbstractOioMessageChannel
|
||||
* {@link} has no parent as it was created by your self.
|
||||
* @param ch the {@link SctpChannel} which is used by this instance
|
||||
*/
|
||||
public OioSctpChannel(Channel parent, EventLoop eventLoop, SctpChannel ch) {
|
||||
super(parent, eventLoop);
|
||||
public OioSctpChannel(Channel parent, SctpChannel ch) {
|
||||
super(parent);
|
||||
this.ch = ch;
|
||||
boolean success = false;
|
||||
try {
|
||||
|
@ -22,9 +22,7 @@ import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.oio.AbstractOioMessageServerChannel;
|
||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||
import io.netty.channel.sctp.DefaultSctpServerChannelConfig;
|
||||
import io.netty.channel.sctp.SctpServerChannelConfig;
|
||||
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,
|
||||
* 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 {
|
||||
|
||||
private static final InternalLogger logger =
|
||||
@ -72,8 +70,8 @@ public class OioSctpServerChannel extends AbstractOioMessageServerChannel
|
||||
/**
|
||||
* Create a new instance with an new {@link SctpServerChannel}
|
||||
*/
|
||||
public OioSctpServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
this(eventLoop, childGroup, newServerSocket());
|
||||
public OioSctpServerChannel() {
|
||||
this(newServerSocket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,8 +79,8 @@ public class OioSctpServerChannel extends AbstractOioMessageServerChannel
|
||||
*
|
||||
* @param sch the {@link SctpServerChannel} which is used by this instance
|
||||
*/
|
||||
public OioSctpServerChannel(EventLoop eventLoop, EventLoopGroup childGroup, SctpServerChannel sch) {
|
||||
super(null, eventLoop, childGroup);
|
||||
public OioSctpServerChannel(SctpServerChannel sch) {
|
||||
super(null);
|
||||
if (sch == null) {
|
||||
throw new NullPointerException("sctp server channel");
|
||||
}
|
||||
@ -198,7 +196,7 @@ public class OioSctpServerChannel extends AbstractOioMessageServerChannel
|
||||
if (key.isAcceptable()) {
|
||||
s = sch.accept();
|
||||
if (s != null) {
|
||||
buf.add(new OioSctpChannel(this, childEventLoopGroup().next(), s));
|
||||
buf.add(new OioSctpChannel(this, s));
|
||||
acceptedChannels ++;
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,7 @@ import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.ServerSocketChannelUDT;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.AbstractNioMessageServerChannel;
|
||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||
import io.netty.channel.udt.DefaultUdtServerChannelConfig;
|
||||
import io.netty.channel.udt.UdtServerChannel;
|
||||
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.
|
||||
*/
|
||||
public abstract class NioUdtAcceptorChannel extends AbstractNioMessageServerChannel implements UdtServerChannel {
|
||||
public abstract class NioUdtAcceptorChannel extends AbstractNioMessageChannel implements UdtServerChannel {
|
||||
|
||||
protected static final InternalLogger logger =
|
||||
InternalLoggerFactory.getInstance(NioUdtAcceptorChannel.class);
|
||||
|
||||
private final UdtServerChannelConfig config;
|
||||
|
||||
protected NioUdtAcceptorChannel(EventLoop eventLoop, EventLoopGroup childGroup,
|
||||
ServerSocketChannelUDT channelUDT) {
|
||||
super(null, eventLoop, childGroup, channelUDT, OP_ACCEPT);
|
||||
protected NioUdtAcceptorChannel(final ServerSocketChannelUDT channelUDT) {
|
||||
super(null, channelUDT, OP_ACCEPT);
|
||||
try {
|
||||
channelUDT.configureBlocking(false);
|
||||
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) {
|
||||
this(eventLoop, childGroup, NioUdtProvider.newAcceptorChannelUDT(type));
|
||||
protected NioUdtAcceptorChannel(final TypeUDT type) {
|
||||
this(NioUdtProvider.newAcceptorChannelUDT(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,8 +18,6 @@ package io.netty.channel.udt.nio;
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.SocketChannelUDT;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -30,8 +28,8 @@ public class NioUdtByteAcceptorChannel extends NioUdtAcceptorChannel {
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||
|
||||
public NioUdtByteAcceptorChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
super(eventLoop, childGroup, TypeUDT.STREAM);
|
||||
public NioUdtByteAcceptorChannel() {
|
||||
super(TypeUDT.STREAM);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,7 +38,7 @@ public class NioUdtByteAcceptorChannel extends NioUdtAcceptorChannel {
|
||||
if (channelUDT == null) {
|
||||
return 0;
|
||||
} else {
|
||||
buf.add(new NioUdtByteConnectorChannel(this, childEventLoopGroup().next(), channelUDT));
|
||||
buf.add(new NioUdtByteConnectorChannel(this, channelUDT));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.FileRegion;
|
||||
import io.netty.channel.nio.AbstractNioByteChannel;
|
||||
import io.netty.channel.udt.DefaultUdtChannelConfig;
|
||||
@ -47,12 +46,12 @@ public class NioUdtByteConnectorChannel extends AbstractNioByteChannel implement
|
||||
|
||||
private final UdtChannelConfig config;
|
||||
|
||||
public NioUdtByteConnectorChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, TypeUDT.STREAM);
|
||||
public NioUdtByteConnectorChannel() {
|
||||
this(TypeUDT.STREAM);
|
||||
}
|
||||
|
||||
public NioUdtByteConnectorChannel(Channel parent, EventLoop eventLoop, SocketChannelUDT channelUDT) {
|
||||
super(parent, eventLoop, channelUDT);
|
||||
public NioUdtByteConnectorChannel(final Channel parent, final SocketChannelUDT channelUDT) {
|
||||
super(parent, channelUDT);
|
||||
try {
|
||||
channelUDT.configureBlocking(false);
|
||||
switch (channelUDT.socketUDT().status()) {
|
||||
@ -76,12 +75,12 @@ public class NioUdtByteConnectorChannel extends AbstractNioByteChannel implement
|
||||
}
|
||||
}
|
||||
|
||||
public NioUdtByteConnectorChannel(EventLoop eventLoop, final SocketChannelUDT channelUDT) {
|
||||
this(null, eventLoop, channelUDT);
|
||||
public NioUdtByteConnectorChannel(final SocketChannelUDT channelUDT) {
|
||||
this(null, channelUDT);
|
||||
}
|
||||
|
||||
public NioUdtByteConnectorChannel(EventLoop eventLoop, final TypeUDT type) {
|
||||
this(eventLoop, NioUdtProvider.newConnectorChannelUDT(type));
|
||||
public NioUdtByteConnectorChannel(final TypeUDT type) {
|
||||
this(NioUdtProvider.newConnectorChannelUDT(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,17 +15,15 @@
|
||||
*/
|
||||
package io.netty.channel.udt.nio;
|
||||
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import io.netty.channel.EventLoop;
|
||||
|
||||
/**
|
||||
* Byte Channel Rendezvous for UDT Streams.
|
||||
*/
|
||||
public class NioUdtByteRendezvousChannel extends NioUdtByteConnectorChannel {
|
||||
|
||||
public NioUdtByteRendezvousChannel(EventLoop eventLoop) {
|
||||
super(eventLoop, NioUdtProvider.newRendezvousChannelUDT(TypeUDT.STREAM));
|
||||
public NioUdtByteRendezvousChannel() {
|
||||
super(NioUdtProvider.newRendezvousChannelUDT(TypeUDT.STREAM));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ package io.netty.channel.udt.nio;
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import com.barchart.udt.nio.SocketChannelUDT;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -30,8 +28,8 @@ public class NioUdtMessageAcceptorChannel extends NioUdtAcceptorChannel {
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||
|
||||
public NioUdtMessageAcceptorChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
super(eventLoop, childGroup, TypeUDT.DATAGRAM);
|
||||
public NioUdtMessageAcceptorChannel() {
|
||||
super(TypeUDT.DATAGRAM);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -40,7 +38,7 @@ public class NioUdtMessageAcceptorChannel extends NioUdtAcceptorChannel {
|
||||
if (channelUDT == null) {
|
||||
return 0;
|
||||
} else {
|
||||
buf.add(new NioUdtMessageConnectorChannel(this, childEventLoopGroup().next(), channelUDT));
|
||||
buf.add(new NioUdtMessageConnectorChannel(this, channelUDT));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||
import io.netty.channel.udt.DefaultUdtChannelConfig;
|
||||
import io.netty.channel.udt.UdtChannel;
|
||||
@ -51,12 +50,12 @@ public class NioUdtMessageConnectorChannel extends AbstractNioMessageChannel imp
|
||||
|
||||
private final UdtChannelConfig config;
|
||||
|
||||
public NioUdtMessageConnectorChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, TypeUDT.DATAGRAM);
|
||||
public NioUdtMessageConnectorChannel() {
|
||||
this(TypeUDT.DATAGRAM);
|
||||
}
|
||||
|
||||
public NioUdtMessageConnectorChannel(final Channel parent, EventLoop eventLoop, final SocketChannelUDT channelUDT) {
|
||||
super(parent, eventLoop, channelUDT, OP_READ);
|
||||
public NioUdtMessageConnectorChannel(final Channel parent, final SocketChannelUDT channelUDT) {
|
||||
super(parent, channelUDT, OP_READ);
|
||||
try {
|
||||
channelUDT.configureBlocking(false);
|
||||
switch (channelUDT.socketUDT().status()) {
|
||||
@ -80,12 +79,12 @@ public class NioUdtMessageConnectorChannel extends AbstractNioMessageChannel imp
|
||||
}
|
||||
}
|
||||
|
||||
public NioUdtMessageConnectorChannel(EventLoop eventLoop, final SocketChannelUDT channelUDT) {
|
||||
this(null, eventLoop, channelUDT);
|
||||
public NioUdtMessageConnectorChannel(final SocketChannelUDT channelUDT) {
|
||||
this(null, channelUDT);
|
||||
}
|
||||
|
||||
public NioUdtMessageConnectorChannel(EventLoop eventLoop, final TypeUDT type) {
|
||||
this(eventLoop, NioUdtProvider.newConnectorChannelUDT(type));
|
||||
public NioUdtMessageConnectorChannel(final TypeUDT type) {
|
||||
this(NioUdtProvider.newConnectorChannelUDT(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,7 +16,6 @@
|
||||
package io.netty.channel.udt.nio;
|
||||
|
||||
import com.barchart.udt.TypeUDT;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.udt.UdtMessage;
|
||||
|
||||
/**
|
||||
@ -24,9 +23,10 @@ import io.netty.channel.udt.UdtMessage;
|
||||
* <p>
|
||||
* Note: send/receive must use {@link UdtMessage} in the pipeline
|
||||
*/
|
||||
public class NioUdtMessageRendezvousChannel extends NioUdtMessageConnectorChannel {
|
||||
public class NioUdtMessageRendezvousChannel extends
|
||||
NioUdtMessageConnectorChannel {
|
||||
|
||||
public NioUdtMessageRendezvousChannel(EventLoop eventLoop) {
|
||||
super(eventLoop, NioUdtProvider.newRendezvousChannelUDT(TypeUDT.DATAGRAM));
|
||||
public NioUdtMessageRendezvousChannel() {
|
||||
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.SocketChannelUDT;
|
||||
import io.netty.bootstrap.ChannelFactory;
|
||||
import io.netty.bootstrap.ServerChannelFactory;
|
||||
import io.netty.channel.Channel;
|
||||
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.UdtChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
@ -42,21 +39,21 @@ import java.nio.channels.spi.SelectorProvider;
|
||||
* <p>
|
||||
* 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}
|
||||
* and {@link KindUDT#ACCEPTOR}.
|
||||
*/
|
||||
public static final ServerChannelFactory<UdtServerChannel> BYTE_ACCEPTOR =
|
||||
new NioUdtServerChannelFactory<UdtServerChannel>(TypeUDT.STREAM, KindUDT.ACCEPTOR);
|
||||
public static final ChannelFactory<UdtServerChannel> BYTE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(
|
||||
TypeUDT.STREAM, KindUDT.ACCEPTOR);
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Byte Connector. See {@link TypeUDT#STREAM}
|
||||
* and {@link KindUDT#CONNECTOR}.
|
||||
*/
|
||||
public static final ChannelFactory<UdtChannel> BYTE_CONNECTOR =
|
||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.STREAM, KindUDT.CONNECTOR);
|
||||
public static final ChannelFactory<UdtChannel> BYTE_CONNECTOR = new NioUdtProvider<UdtChannel>(
|
||||
TypeUDT.STREAM, KindUDT.CONNECTOR);
|
||||
|
||||
/**
|
||||
* {@link SelectorProvider} for UDT Byte channels. See
|
||||
@ -68,22 +65,22 @@ public abstract class NioUdtProvider {
|
||||
* {@link ChannelFactory} for UDT Byte Rendezvous. See
|
||||
* {@link TypeUDT#STREAM} and {@link KindUDT#RENDEZVOUS}.
|
||||
*/
|
||||
public static final ChannelFactory<UdtChannel> BYTE_RENDEZVOUS =
|
||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.STREAM, KindUDT.RENDEZVOUS);
|
||||
public static final ChannelFactory<UdtChannel> BYTE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(
|
||||
TypeUDT.STREAM, KindUDT.RENDEZVOUS);
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Message Acceptor. See
|
||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#ACCEPTOR}.
|
||||
*/
|
||||
public static final ServerChannelFactory<UdtServerChannel> MESSAGE_ACCEPTOR =
|
||||
new NioUdtServerChannelFactory<UdtServerChannel>(TypeUDT.DATAGRAM, KindUDT.ACCEPTOR);
|
||||
public static final ChannelFactory<UdtServerChannel> MESSAGE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(
|
||||
TypeUDT.DATAGRAM, KindUDT.ACCEPTOR);
|
||||
|
||||
/**
|
||||
* {@link ChannelFactory} for UDT Message Connector. See
|
||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#CONNECTOR}.
|
||||
*/
|
||||
public static final ChannelFactory<UdtChannel> MESSAGE_CONNECTOR =
|
||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.DATAGRAM, KindUDT.CONNECTOR);
|
||||
public static final ChannelFactory<UdtChannel> MESSAGE_CONNECTOR = new NioUdtProvider<UdtChannel>(
|
||||
TypeUDT.DATAGRAM, KindUDT.CONNECTOR);
|
||||
|
||||
/**
|
||||
* {@link SelectorProvider} for UDT Message channels. See
|
||||
@ -95,8 +92,8 @@ public abstract class NioUdtProvider {
|
||||
* {@link ChannelFactory} for UDT Message Rendezvous. See
|
||||
* {@link TypeUDT#DATAGRAM} and {@link KindUDT#RENDEZVOUS}.
|
||||
*/
|
||||
public static final ChannelFactory<UdtChannel> MESSAGE_RENDEZVOUS =
|
||||
new NioUdtChannelFactory<UdtChannel>(TypeUDT.DATAGRAM, KindUDT.RENDEZVOUS);
|
||||
public static final ChannelFactory<UdtChannel> MESSAGE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(
|
||||
TypeUDT.DATAGRAM, KindUDT.RENDEZVOUS);
|
||||
|
||||
/**
|
||||
* Expose underlying {@link ChannelUDT} for debugging and monitoring.
|
||||
@ -131,7 +128,8 @@ public abstract class NioUdtProvider {
|
||||
/**
|
||||
* Convenience factory for {@link KindUDT#ACCEPTOR} channels.
|
||||
*/
|
||||
protected static ServerSocketChannelUDT newAcceptorChannelUDT(final TypeUDT type) {
|
||||
protected static ServerSocketChannelUDT newAcceptorChannelUDT(
|
||||
final TypeUDT type) {
|
||||
try {
|
||||
return SelectorProviderUDT.from(type).openServerSocketChannel();
|
||||
} catch (final IOException e) {
|
||||
@ -153,7 +151,8 @@ public abstract class NioUdtProvider {
|
||||
/**
|
||||
* Convenience factory for {@link KindUDT#RENDEZVOUS} channels.
|
||||
*/
|
||||
protected static RendezvousChannelUDT newRendezvousChannelUDT(final TypeUDT type) {
|
||||
protected static RendezvousChannelUDT newRendezvousChannelUDT(
|
||||
final TypeUDT type) {
|
||||
try {
|
||||
return SelectorProviderUDT.from(type).openRendezvousChannel();
|
||||
} 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")
|
||||
@Override
|
||||
public T newChannel(EventLoop eventLoop) {
|
||||
switch (kind()) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T newChannel() {
|
||||
switch (kind) {
|
||||
case ACCEPTOR:
|
||||
throw new IllegalStateException("wrong kind: " + kind());
|
||||
case CONNECTOR:
|
||||
switch (type()) {
|
||||
case DATAGRAM:
|
||||
return (T) new NioUdtMessageConnectorChannel(eventLoop);
|
||||
case STREAM:
|
||||
return (T) new NioUdtByteConnectorChannel(eventLoop);
|
||||
default:
|
||||
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());
|
||||
switch (type) {
|
||||
case DATAGRAM:
|
||||
return (T) new NioUdtMessageAcceptorChannel();
|
||||
case STREAM:
|
||||
return (T) new NioUdtByteAcceptorChannel();
|
||||
default:
|
||||
throw new IllegalStateException("wrong type=" + type);
|
||||
}
|
||||
case CONNECTOR:
|
||||
switch (type) {
|
||||
case DATAGRAM:
|
||||
return (T) new NioUdtMessageConnectorChannel();
|
||||
case STREAM:
|
||||
return (T) new NioUdtByteConnectorChannel();
|
||||
default:
|
||||
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());
|
||||
}
|
||||
throw new IllegalStateException("wrong kind=" + kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
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 org.junit.Test;
|
||||
|
||||
@ -30,7 +28,6 @@ public class NioUdtByteAcceptorChannelTest extends AbstractUdtTest {
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
EventLoop loop = new NioEventLoopGroup().next();
|
||||
assertFalse(new NioUdtByteAcceptorChannel(loop, new NioEventLoopGroup()).metadata().hasDisconnect());
|
||||
assertEquals(false, new NioUdtByteAcceptorChannel().metadata().hasDisconnect());
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
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 org.junit.Test;
|
||||
|
||||
@ -30,7 +28,6 @@ public class NioUdtByteConnectorChannelTest extends AbstractUdtTest {
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
EventLoop loop = new NioEventLoopGroup().next();
|
||||
assertFalse(new NioUdtByteConnectorChannel(loop).metadata().hasDisconnect());
|
||||
assertEquals(false, new NioUdtByteConnectorChannel().metadata().hasDisconnect());
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.udt.nio.NioUdtByteRendezvousChannel;
|
||||
import io.netty.channel.udt.nio.NioUdtProvider;
|
||||
@ -45,8 +44,7 @@ public class NioUdtByteRendezvousChannelTest extends AbstractUdtTest {
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
EventLoop loop = new NioEventLoopGroup().next();
|
||||
assertFalse(new NioUdtByteRendezvousChannel(loop).metadata().hasDisconnect());
|
||||
assertFalse(new NioUdtByteRendezvousChannel().metadata().hasDisconnect());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
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 org.junit.Test;
|
||||
|
||||
@ -30,7 +28,6 @@ public class NioUdtMessageAcceptorChannelTest extends AbstractUdtTest {
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
EventLoop loop = new NioEventLoopGroup().next();
|
||||
assertFalse(new NioUdtMessageAcceptorChannel(loop, new NioEventLoopGroup()).metadata().hasDisconnect());
|
||||
assertEquals(false, new NioUdtMessageAcceptorChannel().metadata().hasDisconnect());
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
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 org.junit.Test;
|
||||
|
||||
@ -30,7 +28,6 @@ public class NioUdtMessageConnectorChannelTest extends AbstractUdtTest {
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
EventLoop loop = new NioEventLoopGroup().next();
|
||||
assertFalse(new NioUdtMessageConnectorChannel(loop).metadata().hasDisconnect());
|
||||
assertEquals(false, new NioUdtMessageConnectorChannel().metadata().hasDisconnect());
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import com.yammer.metrics.Metrics;
|
||||
import com.yammer.metrics.core.Meter;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.udt.nio.NioUdtMessageRendezvousChannel;
|
||||
import io.netty.channel.udt.nio.NioUdtProvider;
|
||||
@ -45,8 +44,7 @@ public class NioUdtMessageRendezvousChannelTest extends AbstractUdtTest {
|
||||
*/
|
||||
@Test
|
||||
public void metadata() throws Exception {
|
||||
EventLoop loop = new NioEventLoopGroup().next();
|
||||
assertFalse(new NioUdtMessageRendezvousChannel(loop).metadata().hasDisconnect());
|
||||
assertFalse(new NioUdtMessageRendezvousChannel().metadata().hasDisconnect());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,9 +16,6 @@
|
||||
|
||||
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.nio.NioUdtProvider;
|
||||
import org.junit.Test;
|
||||
@ -32,22 +29,18 @@ public class NioUdtProviderTest extends AbstractUdtTest {
|
||||
*/
|
||||
@Test
|
||||
public void provideFactory() {
|
||||
|
||||
EventLoop loop = new NioEventLoopGroup().next();
|
||||
EventLoopGroup childGroup = new NioEventLoopGroup();
|
||||
|
||||
// bytes
|
||||
assertNotNull(NioUdtProvider.BYTE_ACCEPTOR.newChannel(loop, childGroup));
|
||||
assertNotNull(NioUdtProvider.BYTE_CONNECTOR.newChannel(loop));
|
||||
assertNotNull(NioUdtProvider.BYTE_RENDEZVOUS.newChannel(loop));
|
||||
assertNotNull(NioUdtProvider.BYTE_ACCEPTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.BYTE_CONNECTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.BYTE_RENDEZVOUS.newChannel());
|
||||
|
||||
// message
|
||||
assertNotNull(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel(loop, childGroup));
|
||||
assertNotNull(NioUdtProvider.MESSAGE_CONNECTOR.newChannel(loop));
|
||||
assertNotNull(NioUdtProvider.MESSAGE_RENDEZVOUS.newChannel(loop));
|
||||
assertNotNull(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.MESSAGE_CONNECTOR.newChannel());
|
||||
assertNotNull(NioUdtProvider.MESSAGE_RENDEZVOUS.newChannel());
|
||||
|
||||
// acceptor types
|
||||
assertTrue(NioUdtProvider.BYTE_ACCEPTOR.newChannel(loop, childGroup) instanceof UdtServerChannel);
|
||||
assertTrue(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel(loop, childGroup) instanceof UdtServerChannel);
|
||||
assertTrue(NioUdtProvider.BYTE_ACCEPTOR.newChannel() instanceof UdtServerChannel);
|
||||
assertTrue(NioUdtProvider.MESSAGE_ACCEPTOR.newChannel() instanceof UdtServerChannel);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package io.netty.bootstrap;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@ -24,7 +25,6 @@ import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.DefaultChannelPromise;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.VoidChannel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
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 {
|
||||
|
||||
private volatile EventLoopGroup group;
|
||||
private volatile ChannelFactory<? extends C> channelFactory;
|
||||
private volatile SocketAddress localAddress;
|
||||
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, 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) {
|
||||
group = bootstrap.group;
|
||||
channelFactory = bootstrap.channelFactory;
|
||||
handler = bootstrap.handler;
|
||||
localAddress = bootstrap.localAddress;
|
||||
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")
|
||||
public B group(EventLoopGroup group) {
|
||||
@ -82,6 +85,38 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
||||
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.
|
||||
*
|
||||
@ -166,6 +201,9 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
||||
if (group == null) {
|
||||
throw new IllegalStateException("group not set");
|
||||
}
|
||||
if (channelFactory == null) {
|
||||
throw new IllegalStateException("factory not set");
|
||||
}
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
@ -255,16 +293,8 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
||||
return promise;
|
||||
}
|
||||
|
||||
abstract Channel createChannel();
|
||||
|
||||
final ChannelFuture initAndRegister() {
|
||||
Channel channel;
|
||||
try {
|
||||
channel = createChannel();
|
||||
} catch (Throwable t) {
|
||||
return VoidChannel.INSTANCE.newFailedFuture(t);
|
||||
}
|
||||
|
||||
final Channel channel = channelFactory().newChannel();
|
||||
try {
|
||||
init(channel);
|
||||
} catch (Throwable t) {
|
||||
@ -272,8 +302,7 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
||||
return channel.newFailedFuture(t);
|
||||
}
|
||||
|
||||
ChannelPromise regFuture = channel.newPromise();
|
||||
channel.unsafe().register(regFuture);
|
||||
ChannelFuture regFuture = group().register(channel);
|
||||
if (regFuture.cause() != null) {
|
||||
if (channel.isRegistered()) {
|
||||
channel.close();
|
||||
@ -330,6 +359,10 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
||||
return localAddress;
|
||||
}
|
||||
|
||||
final ChannelFactory<? extends C> channelFactory() {
|
||||
return channelFactory;
|
||||
}
|
||||
|
||||
final ChannelHandler 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(", ");
|
||||
}
|
||||
if (channelFactory != null) {
|
||||
buf.append("channelFactory: ");
|
||||
buf.append(channelFactory);
|
||||
buf.append(", ");
|
||||
}
|
||||
if (localAddress != null) {
|
||||
buf.append("localAddress: ");
|
||||
buf.append(localAddress);
|
||||
@ -391,4 +429,26 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C ext
|
||||
}
|
||||
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;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.ServerChannel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
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 volatile ChannelFactory<? extends Channel> channelFactory;
|
||||
|
||||
private volatile SocketAddress remoteAddress;
|
||||
|
||||
public Bootstrap() { }
|
||||
|
||||
private Bootstrap(Bootstrap bootstrap) {
|
||||
super(bootstrap);
|
||||
channelFactory = bootstrap.channelFactory;
|
||||
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
|
||||
* is called.
|
||||
@ -255,9 +207,6 @@ public final class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
|
||||
if (handler() == null) {
|
||||
throw new IllegalStateException("handler not set");
|
||||
}
|
||||
if (channelFactory == null) {
|
||||
throw new IllegalStateException("channel or channelFactory not set");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -281,28 +230,4 @@ public final class Bootstrap extends AbstractBootstrap<Bootstrap, Channel> {
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
* {@link ServerBootstrap#bind()}.
|
||||
*/
|
||||
public interface ChannelFactory<T extends 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.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.ChannelHandlerAdapter;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.ServerChannel;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
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 volatile ServerChannelFactory<? extends ServerChannel> channelFactory;
|
||||
private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
|
||||
private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
||||
private volatile EventLoopGroup childGroup;
|
||||
@ -58,7 +55,6 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
||||
|
||||
private ServerBootstrap(ServerBootstrap bootstrap) {
|
||||
super(bootstrap);
|
||||
channelFactory = bootstrap.channelFactory;
|
||||
childGroup = bootstrap.childGroup;
|
||||
childHandler = bootstrap.childHandler;
|
||||
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).
|
||||
*/
|
||||
@ -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
|
||||
* {@link EventExecutorGroup}'s are used to handle all the events and IO for {@link SocketChannel} and
|
||||
* Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These
|
||||
* {@link EventLoopGroup}'s are used to handle all the events and IO for {@link SocketChannel} and
|
||||
* {@link Channel}'s.
|
||||
*/
|
||||
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
|
||||
@ -212,6 +167,7 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
||||
p.addLast(handler());
|
||||
}
|
||||
|
||||
final EventLoopGroup currentChildGroup = childGroup;
|
||||
final ChannelHandler currentChildHandler = childHandler;
|
||||
final Entry<ChannelOption<?>, Object>[] currentChildOptions;
|
||||
final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
|
||||
@ -225,8 +181,8 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
||||
p.addLast(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
public void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline().addLast(new ServerBootstrapAcceptor(currentChildHandler, currentChildOptions,
|
||||
currentChildAttrs));
|
||||
ch.pipeline().addLast(new ServerBootstrapAcceptor(
|
||||
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.");
|
||||
childGroup = group();
|
||||
}
|
||||
if (channelFactory == null) {
|
||||
throw new IllegalStateException("channel or channelFactory not set");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -259,12 +212,16 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
||||
|
||||
private static class ServerBootstrapAcceptor extends ChannelHandlerAdapter {
|
||||
|
||||
private final EventLoopGroup childGroup;
|
||||
private final ChannelHandler childHandler;
|
||||
private final Entry<ChannelOption<?>, Object>[] childOptions;
|
||||
private final Entry<AttributeKey<?>, Object>[] childAttrs;
|
||||
|
||||
ServerBootstrapAcceptor(ChannelHandler childHandler, Entry<ChannelOption<?>, Object>[] childOptions,
|
||||
Entry<AttributeKey<?>, Object>[] childAttrs) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ServerBootstrapAcceptor(
|
||||
EventLoopGroup childGroup, ChannelHandler childHandler,
|
||||
Entry<ChannelOption<?>, Object>[] childOptions, Entry<AttributeKey<?>, Object>[] childAttrs) {
|
||||
this.childGroup = childGroup;
|
||||
this.childHandler = childHandler;
|
||||
this.childOptions = childOptions;
|
||||
this.childAttrs = childAttrs;
|
||||
@ -273,7 +230,7 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
Channel child = (Channel) msg;
|
||||
final Channel child = (Channel) msg;
|
||||
|
||||
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.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
|
||||
@ -304,7 +277,7 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
||||
ctx.channel().eventLoop().schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
config.setAutoRead(true);
|
||||
config.setAutoRead(true);
|
||||
}
|
||||
}, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
@ -358,29 +331,5 @@ public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, Se
|
||||
|
||||
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 remoteAddress;
|
||||
private final EventLoop eventLoop;
|
||||
private volatile EventLoop eventLoop;
|
||||
private volatile boolean registered;
|
||||
|
||||
/** Cache for the string representation of this channel */
|
||||
@ -72,9 +72,8 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
* @param 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.eventLoop = validate(eventLoop);
|
||||
unsafe = newUnsafe();
|
||||
pipeline = new DefaultChannelPipeline(this);
|
||||
}
|
||||
@ -107,6 +106,10 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
|
||||
@Override
|
||||
public EventLoop eventLoop() {
|
||||
EventLoop eventLoop = this.eventLoop;
|
||||
if (eventLoop == null) {
|
||||
throw new IllegalStateException("channel not registered to an event loop");
|
||||
}
|
||||
return eventLoop;
|
||||
}
|
||||
|
||||
@ -179,6 +182,11 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
return pipeline.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture deregister() {
|
||||
return pipeline.deregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel flush() {
|
||||
pipeline.flush();
|
||||
@ -210,6 +218,11 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
return pipeline.close(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture deregister(ChannelPromise promise) {
|
||||
return pipeline.deregister(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel read() {
|
||||
pipeline.read();
|
||||
@ -375,7 +388,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
|
||||
@Override
|
||||
public final ChannelHandlerInvoker invoker() {
|
||||
return eventLoop.asInvoker();
|
||||
return eventLoop().asInvoker();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -394,7 +407,22 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
}
|
||||
|
||||
@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()) {
|
||||
register0(promise);
|
||||
} 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) {
|
||||
safeSetSuccess(promise);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -577,6 +611,18 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
|
||||
} finally {
|
||||
if (registered) {
|
||||
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}.
|
||||
*/
|
||||
|
@ -34,14 +34,11 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||
|
||||
private final EventLoopGroup childGroup;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*/
|
||||
protected AbstractServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
super(null, eventLoop);
|
||||
this.childGroup = childGroup;
|
||||
protected AbstractServerChannel() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,11 +71,6 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventLoopGroup childEventLoopGroup() {
|
||||
return childGroup;
|
||||
}
|
||||
|
||||
private final class DefaultServerUnsafe extends AbstractUnsafe {
|
||||
@Override
|
||||
public void write(Object msg, ChannelPromise promise) {
|
||||
|
@ -280,6 +280,19 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
||||
*/
|
||||
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
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* {@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 #closeForcibly()}</li>
|
||||
* <li>{@link #register(ChannelPromise)}</li>
|
||||
* <li>{@link #deregister(ChannelPromise)}</li>
|
||||
* <li>{@link #voidPromise()}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@ -432,7 +460,7 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
||||
* Register the {@link Channel} of the {@link ChannelPromise} and notify
|
||||
* 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
|
||||
@ -467,6 +495,12 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
|
||||
*/
|
||||
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
|
||||
* {@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;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -276,6 +281,15 @@ public interface ChannelHandler {
|
||||
*/
|
||||
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()}.
|
||||
*/
|
||||
|
@ -102,6 +102,18 @@ public class ChannelHandlerAdapter implements ChannelHandler {
|
||||
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
|
||||
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
||||
@ -224,6 +236,18 @@ public class ChannelHandlerAdapter implements ChannelHandler {
|
||||
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
|
||||
* to the next {@link ChannelHandler} in the {@link ChannelPipeline}.
|
||||
|
@ -192,7 +192,10 @@ public class ChannelHandlerAppender extends ChannelHandlerAdapter {
|
||||
} else {
|
||||
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 {
|
||||
if (selfRemoval) {
|
||||
|
@ -175,6 +175,15 @@ public interface ChannelHandlerContext extends AttributeMap {
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -295,6 +304,19 @@ public interface ChannelHandlerContext extends AttributeMap {
|
||||
*/
|
||||
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
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* {@link ChannelHandler#channelRead(ChannelHandlerContext, Object)} event if data was
|
||||
|
@ -39,6 +39,13 @@ public interface ChannelHandlerInvoker {
|
||||
*/
|
||||
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
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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)}.
|
||||
* 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) {
|
||||
try {
|
||||
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) {
|
||||
try {
|
||||
ctx.handler().read(ctx);
|
||||
|
@ -17,6 +17,7 @@ package io.netty.channel;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.util.concurrent.DefaultEventExecutorGroup;
|
||||
import io.netty.util.concurrent.EventExecutor;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
|
||||
import java.net.ConnectException;
|
||||
@ -661,6 +662,15 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -781,6 +791,19 @@ public interface ChannelPipeline extends Iterable<Entry<String, ChannelHandler>>
|
||||
*/
|
||||
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
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* {@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;
|
||||
private static final int MASK_EXCEPTION_CAUGHT = 1 << 2;
|
||||
private static final int MASK_CHANNEL_REGISTERED = 1 << 3;
|
||||
private static final int MASK_CHANNEL_ACTIVE = 1 << 4;
|
||||
private static final int MASK_CHANNEL_INACTIVE = 1 << 5;
|
||||
private static final int MASK_CHANNEL_READ = 1 << 6;
|
||||
private static final int MASK_CHANNEL_READ_COMPLETE = 1 << 7;
|
||||
private static final int MASK_CHANNEL_WRITABILITY_CHANGED = 1 << 8;
|
||||
private static final int MASK_USER_EVENT_TRIGGERED = 1 << 9;
|
||||
private static final int MASK_BIND = 1 << 10;
|
||||
private static final int MASK_CONNECT = 1 << 11;
|
||||
private static final int MASK_DISCONNECT = 1 << 12;
|
||||
private static final int MASK_CLOSE = 1 << 13;
|
||||
private static final int MASK_READ = 1 << 14;
|
||||
private static final int MASK_WRITE = 1 << 15;
|
||||
private static final int MASK_FLUSH = 1 << 16;
|
||||
private static final int MASK_CHANNEL_UNREGISTERED = 1 << 4;
|
||||
private static final int MASK_CHANNEL_ACTIVE = 1 << 5;
|
||||
private static final int MASK_CHANNEL_INACTIVE = 1 << 6;
|
||||
private static final int MASK_CHANNEL_READ = 1 << 7;
|
||||
private static final int MASK_CHANNEL_READ_COMPLETE = 1 << 8;
|
||||
private static final int MASK_CHANNEL_WRITABILITY_CHANGED = 1 << 9;
|
||||
private static final int MASK_USER_EVENT_TRIGGERED = 1 << 10;
|
||||
private static final int MASK_BIND = 1 << 11;
|
||||
private static final int MASK_CONNECT = 1 << 12;
|
||||
private static final int MASK_DISCONNECT = 1 << 13;
|
||||
private static final int MASK_CLOSE = 1 << 14;
|
||||
private static final int MASK_DEREGISTER = 1 << 15;
|
||||
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
|
||||
@ -111,6 +113,10 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
"channelRegistered", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||
flags |= MASK_CHANNEL_REGISTERED;
|
||||
}
|
||||
if (handlerType.getMethod(
|
||||
"channelUnregistered", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||
flags |= MASK_CHANNEL_UNREGISTERED;
|
||||
}
|
||||
if (handlerType.getMethod(
|
||||
"channelActive", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||
flags |= MASK_CHANNEL_ACTIVE;
|
||||
@ -153,6 +159,10 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
"close", ChannelHandlerContext.class, ChannelPromise.class).isAnnotationPresent(Skip.class)) {
|
||||
flags |= MASK_CLOSE;
|
||||
}
|
||||
if (handlerType.getMethod(
|
||||
"deregister", ChannelHandlerContext.class, ChannelPromise.class).isAnnotationPresent(Skip.class)) {
|
||||
flags |= MASK_DEREGISTER;
|
||||
}
|
||||
if (handlerType.getMethod(
|
||||
"read", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
|
||||
flags |= MASK_READ;
|
||||
@ -215,14 +225,9 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
this.pipeline = pipeline;
|
||||
this.name = name;
|
||||
this.handler = handler;
|
||||
this.invoker = invoker;
|
||||
|
||||
skipFlags = skipFlags(handler);
|
||||
|
||||
if (invoker == null) {
|
||||
this.invoker = channel.unsafe().invoker();
|
||||
} else {
|
||||
this.invoker = invoker;
|
||||
}
|
||||
}
|
||||
|
||||
/** Invocation initiated by {@link DefaultChannelPipeline#teardownAll()}}. */
|
||||
@ -267,11 +272,14 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
|
||||
@Override
|
||||
public EventExecutor executor() {
|
||||
return invoker.executor();
|
||||
return invoker().executor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerInvoker invoker() {
|
||||
if (invoker == null) {
|
||||
return channel.unsafe().invoker();
|
||||
}
|
||||
return invoker;
|
||||
}
|
||||
|
||||
@ -293,35 +301,42 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
@Override
|
||||
public ChannelHandlerContext fireChannelRegistered() {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext fireChannelActive() {
|
||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_ACTIVE);
|
||||
next.invoker.invokeChannelActive(next);
|
||||
next.invoker().invokeChannelActive(next);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext fireChannelInactive() {
|
||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_INACTIVE);
|
||||
next.invoker.invokeChannelInactive(next);
|
||||
next.invoker().invokeChannelInactive(next);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext fireExceptionCaught(Throwable cause) {
|
||||
DefaultChannelHandlerContext next = findContextInbound(MASK_EXCEPTION_CAUGHT);
|
||||
next.invoker.invokeExceptionCaught(next, cause);
|
||||
next.invoker().invokeExceptionCaught(next, cause);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext fireUserEventTriggered(Object event) {
|
||||
DefaultChannelHandlerContext next = findContextInbound(MASK_USER_EVENT_TRIGGERED);
|
||||
next.invoker.invokeUserEventTriggered(next, event);
|
||||
next.invoker().invokeUserEventTriggered(next, event);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -329,21 +344,21 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
public ChannelHandlerContext fireChannelRead(Object msg) {
|
||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_READ);
|
||||
ReferenceCountUtil.touch(msg, next);
|
||||
next.invoker.invokeChannelRead(next, msg);
|
||||
next.invoker().invokeChannelRead(next, msg);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext fireChannelReadComplete() {
|
||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_READ_COMPLETE);
|
||||
next.invoker.invokeChannelReadComplete(next);
|
||||
next.invoker().invokeChannelReadComplete(next);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext fireChannelWritabilityChanged() {
|
||||
DefaultChannelHandlerContext next = findContextInbound(MASK_CHANNEL_WRITABILITY_CHANGED);
|
||||
next.invoker.invokeChannelWritabilityChanged(next);
|
||||
next.invoker().invokeChannelWritabilityChanged(next);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -372,10 +387,15 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
return close(newPromise());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture deregister() {
|
||||
return deregister(newPromise());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture bind(final SocketAddress localAddress, final ChannelPromise promise) {
|
||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_BIND);
|
||||
next.invoker.invokeBind(next, localAddress, promise);
|
||||
next.invoker().invokeBind(next, localAddress, promise);
|
||||
return promise;
|
||||
}
|
||||
|
||||
@ -387,7 +407,7 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
|
||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_CONNECT);
|
||||
next.invoker.invokeConnect(next, remoteAddress, localAddress, promise);
|
||||
next.invoker().invokeConnect(next, remoteAddress, localAddress, promise);
|
||||
return promise;
|
||||
}
|
||||
|
||||
@ -398,21 +418,28 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
}
|
||||
|
||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_DISCONNECT);
|
||||
next.invoker.invokeDisconnect(next, promise);
|
||||
next.invoker().invokeDisconnect(next, promise);
|
||||
return promise;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture close(ChannelPromise promise) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext read() {
|
||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_READ);
|
||||
next.invoker.invokeRead(next);
|
||||
next.invoker().invokeRead(next);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -425,14 +452,14 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
public ChannelFuture write(Object msg, ChannelPromise promise) {
|
||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_WRITE);
|
||||
ReferenceCountUtil.touch(msg, next);
|
||||
next.invoker.invokeWrite(next, msg, promise);
|
||||
next.invoker().invokeWrite(next, msg, promise);
|
||||
return promise;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext flush() {
|
||||
DefaultChannelHandlerContext next = findContextOutbound(MASK_FLUSH);
|
||||
next.invoker.invokeFlush(next);
|
||||
next.invoker().invokeFlush(next);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -441,9 +468,9 @@ final class DefaultChannelHandlerContext implements ChannelHandlerContext, Resou
|
||||
DefaultChannelHandlerContext next;
|
||||
next = findContextOutbound(MASK_WRITE);
|
||||
ReferenceCountUtil.touch(msg, next);
|
||||
next.invoker.invokeWrite(next, msg, promise);
|
||||
next.invoker().invokeWrite(next, msg, promise);
|
||||
next = findContextOutbound(MASK_FLUSH);
|
||||
next.invoker.invokeFlush(next);
|
||||
next.invoker().invokeFlush(next);
|
||||
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
|
||||
public void invokeChannelActive(final ChannelHandlerContext ctx) {
|
||||
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
|
||||
public void invokeRead(final ChannelHandlerContext ctx) {
|
||||
if (executor.inEventLoop()) {
|
||||
|
@ -550,6 +550,7 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
try {
|
||||
ctx.handler().handlerAdded(ctx);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
boolean removed = false;
|
||||
try {
|
||||
remove(ctx);
|
||||
@ -802,6 +803,17 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
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
|
||||
* 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
|
||||
public ChannelPipeline fireChannelInactive() {
|
||||
head.fireChannelInactive();
|
||||
teardownAll();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -887,6 +898,11 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
return tail.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture deregister() {
|
||||
return tail.deregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline flush() {
|
||||
tail.flush();
|
||||
@ -918,6 +934,11 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
return tail.close(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture deregister(ChannelPromise promise) {
|
||||
return tail.close(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline read() {
|
||||
tail.read();
|
||||
@ -983,6 +1004,9 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception { }
|
||||
|
||||
@Override
|
||||
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { }
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception { }
|
||||
|
||||
@ -1050,6 +1074,11 @@ final class DefaultChannelPipeline implements ChannelPipeline {
|
||||
unsafe.close(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
|
||||
unsafe.deregister(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ChannelHandlerContext ctx) {
|
||||
unsafe.beginRead();
|
||||
|
@ -25,4 +25,16 @@ import io.netty.util.concurrent.EventExecutorGroup;
|
||||
public interface EventLoopGroup extends EventExecutorGroup {
|
||||
@Override
|
||||
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
|
||||
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;
|
||||
|
||||
/**
|
||||
* A {@link Channel} that accepts an incoming connection attempt and creates its child {@link Channel}s by accepting
|
||||
* them. {@link ServerSocketChannel} is a good example.
|
||||
* A {@link Channel} that accepts an incoming connection attempt and creates
|
||||
* its child {@link Channel}s by accepting them. {@link ServerSocketChannel} is
|
||||
* a good example.
|
||||
*/
|
||||
public interface ServerChannel extends Channel {
|
||||
EventLoopGroup childEventLoopGroup();
|
||||
}
|
||||
public interface ServerChannel extends Channel { }
|
||||
|
@ -51,13 +51,31 @@ public abstract class SingleThreadEventLoop extends SingleThreadEventExecutor im
|
||||
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
|
||||
protected boolean wakesUpForTask(Runnable task) {
|
||||
return !(task instanceof NonWakeupRunnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marker interface for {@linkRunnable} that will not trigger an {@link #wakeup(boolean)} in all cases.
|
||||
* Marker interface for {@link Runnable} that will not trigger an {@link #wakeup(boolean)} in all cases.
|
||||
*/
|
||||
interface NonWakeupRunnable extends Runnable { }
|
||||
}
|
||||
|
@ -30,6 +30,21 @@ public class ThreadPerChannelEventLoop extends SingleThreadEventLoop {
|
||||
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
|
||||
protected void run() {
|
||||
for (;;) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
package io.netty.channel;
|
||||
|
||||
|
||||
import io.netty.util.concurrent.AbstractEventExecutorGroup;
|
||||
import io.netty.util.concurrent.DefaultPromise;
|
||||
import io.netty.util.concurrent.EventExecutor;
|
||||
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}.
|
||||
*/
|
||||
public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
||||
public class ThreadPerChannelEventLoopGroup extends AbstractEventExecutorGroup implements EventLoopGroup {
|
||||
|
||||
private final Object[] childArgs;
|
||||
private final int maxChannels;
|
||||
final Executor executor;
|
||||
final Set<EventLoop> activeChildren =
|
||||
Collections.newSetFromMap(PlatformDependent.<EventLoop, Boolean>newConcurrentHashMap());
|
||||
private final Set<EventLoop> readOnlyActiveChildren = Collections.unmodifiableSet(activeChildren);
|
||||
final Queue<EventLoop> idleChildren = new ConcurrentLinkedQueue<EventLoop>();
|
||||
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
|
||||
* 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) {
|
||||
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
|
||||
* 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
|
||||
* registered {@link Channel}s
|
||||
* @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
|
||||
* 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
|
||||
* registered {@link Channel}s
|
||||
* @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);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends EventExecutor> Set<E> children() {
|
||||
return Collections.unmodifiableSet((Set<E>) activeChildren);
|
||||
return (Set<E>) readOnlyActiveChildren;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventLoop next() {
|
||||
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;
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -271,4 +266,47 @@ public class ThreadPerChannelEventLoopGroup extends AbstractEventLoopGroup {
|
||||
}
|
||||
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 final EmbeddedEventLoop loop;
|
||||
private final EmbeddedEventLoop loop = new EmbeddedEventLoop();
|
||||
private final ChannelConfig config = new DefaultChannelConfig(this);
|
||||
private final Queue<Object> inboundMessages = 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}
|
||||
*/
|
||||
public EmbeddedChannel(ChannelHandler... handlers) {
|
||||
super(null, new EmbeddedEventLoop());
|
||||
|
||||
loop = (EmbeddedEventLoop) eventLoop();
|
||||
super(null);
|
||||
|
||||
if (handlers == null) {
|
||||
throw new NullPointerException("handlers");
|
||||
@ -91,7 +89,7 @@ public class EmbeddedChannel extends AbstractChannel {
|
||||
}
|
||||
|
||||
p.addLast(new LastInboundHandler());
|
||||
unsafe().register(newPromise());
|
||||
loop.register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -16,6 +16,8 @@
|
||||
package io.netty.channel.embedded;
|
||||
|
||||
import io.netty.channel.AbstractEventLoop;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelHandlerInvoker;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
@ -92,6 +94,17 @@ final class EmbeddedEventLoop extends AbstractEventLoop implements ChannelHandle
|
||||
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
|
||||
public boolean inEventLoop() {
|
||||
return true;
|
||||
@ -117,6 +130,11 @@ final class EmbeddedEventLoop extends AbstractEventLoop implements ChannelHandle
|
||||
invokeChannelRegisteredNow(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeChannelUnregistered(ChannelHandlerContext ctx) {
|
||||
invokeChannelUnregisteredNow(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeChannelActive(ChannelHandlerContext ctx) {
|
||||
invokeChannelActiveNow(ctx);
|
||||
@ -174,6 +192,11 @@ final class EmbeddedEventLoop extends AbstractEventLoop implements ChannelHandle
|
||||
invokeCloseNow(ctx, promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeDeregister(ChannelHandlerContext ctx, ChannelPromise promise) {
|
||||
invokeDeregisterNow(ctx, promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invokeRead(ChannelHandlerContext ctx) {
|
||||
invokeReadNow(ctx);
|
||||
|
@ -87,12 +87,12 @@ public class LocalChannel extends AbstractChannel {
|
||||
private volatile boolean readInProgress;
|
||||
private volatile boolean registerInProgress;
|
||||
|
||||
public LocalChannel(EventLoop eventLoop) {
|
||||
super(null, eventLoop);
|
||||
public LocalChannel() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
LocalChannel(LocalServerChannel parent, EventLoop eventLoop, LocalChannel peer) {
|
||||
super(parent, eventLoop);
|
||||
LocalChannel(LocalServerChannel parent, LocalChannel peer) {
|
||||
super(parent);
|
||||
this.peer = peer;
|
||||
localAddress = parent.localAddress();
|
||||
remoteAddress = peer.localAddress();
|
||||
|
@ -20,7 +20,6 @@ import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.DefaultChannelConfig;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.ServerChannel;
|
||||
import io.netty.channel.SingleThreadEventLoop;
|
||||
import io.netty.util.concurrent.SingleThreadEventExecutor;
|
||||
@ -47,10 +46,6 @@ public class LocalServerChannel extends AbstractServerChannel {
|
||||
private volatile LocalAddress localAddress;
|
||||
private volatile boolean acceptInProgress;
|
||||
|
||||
public LocalServerChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
super(eventLoop, childGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelConfig config() {
|
||||
return config;
|
||||
@ -136,7 +131,7 @@ public class LocalServerChannel extends AbstractServerChannel {
|
||||
}
|
||||
|
||||
LocalChannel serve(final LocalChannel peer) {
|
||||
final LocalChannel child = new LocalChannel(this, childEventLoopGroup().next(), peer);
|
||||
final LocalChannel child = new LocalChannel(this, peer);
|
||||
if (eventLoop().inEventLoop()) {
|
||||
serve0(child);
|
||||
} else {
|
||||
|
@ -22,7 +22,6 @@ import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.FileRegion;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
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 ch the underlying {@link SelectableChannel} on which it operates
|
||||
*/
|
||||
protected AbstractNioByteChannel(Channel parent, EventLoop eventLoop, SelectableChannel ch) {
|
||||
super(parent, eventLoop, ch, SelectionKey.OP_READ);
|
||||
protected AbstractNioByteChannel(Channel parent, SelectableChannel ch) {
|
||||
super(parent, ch, SelectionKey.OP_READ);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,8 +65,8 @@ public abstract class AbstractNioChannel extends AbstractChannel {
|
||||
* @param ch the underlying {@link SelectableChannel} on which it operates
|
||||
* @param readInterestOp the ops to set to receive data from the {@link SelectableChannel}
|
||||
*/
|
||||
protected AbstractNioChannel(Channel parent, EventLoop eventLoop, SelectableChannel ch, int readInterestOp) {
|
||||
super(parent, eventLoop);
|
||||
protected AbstractNioChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
|
||||
super(parent);
|
||||
this.ch = ch;
|
||||
this.readInterestOp = readInterestOp;
|
||||
try {
|
||||
|
@ -19,7 +19,6 @@ import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.ServerChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -33,9 +32,11 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
|
||||
|
||||
protected AbstractNioMessageChannel(
|
||||
Channel parent, EventLoop eventLoop, SelectableChannel ch, int readInterestOp) {
|
||||
super(parent, eventLoop, ch, readInterestOp);
|
||||
/**
|
||||
* @see {@link AbstractNioChannel#AbstractNioChannel(Channel, SelectableChannel, int)}
|
||||
*/
|
||||
protected AbstractNioMessageChannel(Channel parent, SelectableChannel ch, int readInterestOp) {
|
||||
super(parent, ch, readInterestOp);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -169,5 +170,4 @@ public abstract class AbstractNioMessageChannel extends AbstractNioChannel {
|
||||
* @return {@code true} if and only if the message has been written
|
||||
*/
|
||||
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.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.FileRegion;
|
||||
import io.netty.channel.socket.ChannelInputShutdownEvent;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
@ -37,8 +36,11 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||
private volatile boolean inputShutdown;
|
||||
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() {
|
||||
|
@ -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
|
||||
|
@ -18,8 +18,6 @@ package io.netty.channel.oio;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -31,8 +29,8 @@ public abstract class AbstractOioMessageChannel extends AbstractOioChannel {
|
||||
|
||||
private final List<Object> readBuf = new ArrayList<Object>();
|
||||
|
||||
protected AbstractOioMessageChannel(Channel parent, EventLoop eventLoop) {
|
||||
super(parent, eventLoop);
|
||||
protected AbstractOioMessageChannel(Channel parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@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.channel.Channel;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.FileRegion;
|
||||
|
||||
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
|
||||
* {@link} has no parent as it was created by your self.
|
||||
*/
|
||||
protected OioByteStreamChannel(Channel parent, EventLoop eventLoop) {
|
||||
super(parent, eventLoop);
|
||||
protected OioByteStreamChannel(Channel parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,7 +25,6 @@ import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||
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}.
|
||||
*/
|
||||
public NioDatagramChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, 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));
|
||||
public NioDatagramChannel() {
|
||||
this(newSocket(DEFAULT_SELECTOR_PROVIDER));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public NioDatagramChannel(EventLoop eventLoop, InternetProtocolFamily ipFamily) {
|
||||
this(eventLoop, newSocket(DEFAULT_SELECTOR_PROVIDER, ipFamily));
|
||||
public NioDatagramChannel(InternetProtocolFamily ipFamily) {
|
||||
this(DEFAULT_SELECTOR_PROVIDER, ipFamily);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance using the given {@link SelectorProvider} and {@link InternetProtocolFamily}.
|
||||
* 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));
|
||||
public NioDatagramChannel(SelectorProvider provider, InternetProtocolFamily ipFamily) {
|
||||
this(newSocket(provider, ipFamily));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from the given {@link DatagramChannel}.
|
||||
*/
|
||||
public NioDatagramChannel(EventLoop eventLoop, DatagramChannel socket) {
|
||||
super(null, eventLoop, socket, SelectionKey.OP_READ);
|
||||
public NioDatagramChannel(DatagramChannel socket) {
|
||||
super(null, socket, SelectionKey.OP_READ);
|
||||
config = new NioDatagramChannelConfig(this, socket);
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,7 @@ package io.netty.channel.socket.nio;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.AbstractNioMessageServerChannel;
|
||||
import io.netty.channel.nio.AbstractNioMessageChannel;
|
||||
import io.netty.channel.socket.DefaultServerSocketChannelConfig;
|
||||
import io.netty.channel.socket.ServerSocketChannelConfig;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
@ -40,8 +38,8 @@ import java.util.List;
|
||||
* A {@link io.netty.channel.socket.ServerSocketChannel} implementation which uses
|
||||
* NIO selector based implementation to accept new connections.
|
||||
*/
|
||||
public class NioServerSocketChannel extends AbstractNioMessageServerChannel
|
||||
implements io.netty.channel.socket.ServerSocketChannel {
|
||||
public class NioServerSocketChannel extends AbstractNioMessageChannel
|
||||
implements io.netty.channel.socket.ServerSocketChannel {
|
||||
|
||||
private static final ChannelMetadata METADATA = new ChannelMetadata(false);
|
||||
private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
|
||||
@ -68,22 +66,12 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel
|
||||
/**
|
||||
* Create a new instance
|
||||
*/
|
||||
public NioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
this(eventLoop, childGroup, newSocket(DEFAULT_SELECTOR_PROVIDER));
|
||||
public NioServerSocketChannel() {
|
||||
this(DEFAULT_SELECTOR_PROVIDER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance using the given {@link SelectorProvider}.
|
||||
*/
|
||||
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);
|
||||
public NioServerSocketChannel(SelectorProvider provider) {
|
||||
super(null, newSocket(provider), SelectionKey.OP_ACCEPT);
|
||||
config = new NioServerSocketChannelConfig(this, javaChannel().socket());
|
||||
}
|
||||
|
||||
@ -138,7 +126,7 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel
|
||||
|
||||
try {
|
||||
if (ch != null) {
|
||||
buf.add(new NioSocketChannel(this, childEventLoopGroup().next(), ch));
|
||||
buf.add(new NioSocketChannel(this, ch));
|
||||
return 1;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
@ -66,32 +66,31 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
|
||||
/**
|
||||
* Create a new instance
|
||||
*/
|
||||
public NioSocketChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, newSocket(DEFAULT_SELECTOR_PROVIDER));
|
||||
public NioSocketChannel() {
|
||||
this(DEFAULT_SELECTOR_PROVIDER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance using the given {@link SelectorProvider}.
|
||||
*/
|
||||
public NioSocketChannel(EventLoop eventLoop, SelectorProvider provider) {
|
||||
this(eventLoop, newSocket(provider));
|
||||
public NioSocketChannel(SelectorProvider provider) {
|
||||
this(newSocket(provider));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance using the given {@link SocketChannel}.
|
||||
*/
|
||||
public NioSocketChannel(EventLoop eventLoop, SocketChannel socket) {
|
||||
this(null, eventLoop, socket);
|
||||
public NioSocketChannel(SocketChannel socket) {
|
||||
this(null, socket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public NioSocketChannel(Channel parent, EventLoop eventLoop, SocketChannel socket) {
|
||||
super(parent, eventLoop, socket);
|
||||
public NioSocketChannel(Channel parent, SocketChannel socket) {
|
||||
super(parent, 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.ChannelOutboundBuffer;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||
import io.netty.channel.socket.DatagramChannel;
|
||||
@ -56,7 +55,8 @@ import java.util.Locale;
|
||||
* @see AddressedEnvelope
|
||||
* @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);
|
||||
|
||||
@ -79,8 +79,8 @@ public final class OioDatagramChannel extends AbstractOioMessageChannel implemen
|
||||
/**
|
||||
* Create a new instance with an new {@link MulticastSocket}.
|
||||
*/
|
||||
public OioDatagramChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, newSocket());
|
||||
public OioDatagramChannel() {
|
||||
this(newSocket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,8 +88,8 @@ public final class OioDatagramChannel extends AbstractOioMessageChannel implemen
|
||||
*
|
||||
* @param socket the {@link MulticastSocket} which is used by this instance
|
||||
*/
|
||||
public OioDatagramChannel(EventLoop eventLoop, MulticastSocket socket) {
|
||||
super(null, eventLoop);
|
||||
public OioDatagramChannel(MulticastSocket socket) {
|
||||
super(null);
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
|
@ -18,9 +18,7 @@ package io.netty.channel.socket.oio;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.ChannelOutboundBuffer;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.oio.AbstractOioMessageServerChannel;
|
||||
import io.netty.channel.oio.AbstractOioMessageChannel;
|
||||
import io.netty.channel.socket.ServerSocketChannel;
|
||||
import io.netty.util.internal.logging.InternalLogger;
|
||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
@ -40,7 +38,8 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
*
|
||||
* 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 =
|
||||
InternalLoggerFactory.getInstance(OioServerSocketChannel.class);
|
||||
@ -62,8 +61,8 @@ public class OioServerSocketChannel extends AbstractOioMessageServerChannel impl
|
||||
/**
|
||||
* Create a new instance with an new {@link Socket}
|
||||
*/
|
||||
public OioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
|
||||
this(eventLoop, childGroup, newServerSocket());
|
||||
public OioServerSocketChannel() {
|
||||
this(newServerSocket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,8 +70,8 @@ public class OioServerSocketChannel extends AbstractOioMessageServerChannel impl
|
||||
*
|
||||
* @param socket the {@link ServerSocket} which is used by this instance
|
||||
*/
|
||||
public OioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup, ServerSocket socket) {
|
||||
super(null, eventLoop, childGroup);
|
||||
public OioServerSocketChannel(ServerSocket socket) {
|
||||
super(null);
|
||||
if (socket == null) {
|
||||
throw new NullPointerException("socket");
|
||||
}
|
||||
@ -155,7 +154,7 @@ public class OioServerSocketChannel extends AbstractOioMessageServerChannel impl
|
||||
Socket s = socket.accept();
|
||||
try {
|
||||
if (s != null) {
|
||||
buf.add(new OioSocketChannel(this, childEventLoopGroup().next(), s));
|
||||
buf.add(new OioSocketChannel(this, s));
|
||||
return 1;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
|
@ -49,8 +49,8 @@ public class OioSocketChannel extends OioByteStreamChannel
|
||||
/**
|
||||
* Create a new instance with an new {@link Socket}
|
||||
*/
|
||||
public OioSocketChannel(EventLoop eventLoop) {
|
||||
this(eventLoop, new Socket());
|
||||
public OioSocketChannel() {
|
||||
this(new Socket());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,8 +58,8 @@ public class OioSocketChannel extends OioByteStreamChannel
|
||||
*
|
||||
* @param socket the {@link Socket} which is used by this instance
|
||||
*/
|
||||
public OioSocketChannel(EventLoop eventLoop, Socket socket) {
|
||||
this(null, eventLoop, socket);
|
||||
public OioSocketChannel(Socket socket) {
|
||||
this(null, socket);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,8 +69,8 @@ public class OioSocketChannel extends OioByteStreamChannel
|
||||
* {@link} has no parent as it was created by your self.
|
||||
* @param socket the {@link Socket} which is used by this instance
|
||||
*/
|
||||
public OioSocketChannel(Channel parent, EventLoop eventLoop, Socket socket) {
|
||||
super(parent, eventLoop);
|
||||
public OioSocketChannel(Channel parent, Socket socket) {
|
||||
super(parent);
|
||||
this.socket = socket;
|
||||
config = new DefaultOioSocketChannelConfig(this, socket);
|
||||
|
||||
|
@ -137,7 +137,7 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
public void testRemoveChannelHandler() {
|
||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
||||
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||
|
||||
ChannelHandler handler1 = newHandler();
|
||||
ChannelHandler handler2 = newHandler();
|
||||
@ -160,7 +160,7 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
public void testReplaceChannelHandler() {
|
||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
||||
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||
|
||||
ChannelHandler handler1 = newHandler();
|
||||
pipeline.addLast("handler1", handler1);
|
||||
@ -185,7 +185,7 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
public void testChannelHandlerContextNavigation() {
|
||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
||||
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||
|
||||
final int HANDLER_ARRAY_LEN = 5;
|
||||
ChannelHandler[] firstHandlers = newHandlers(HANDLER_ARRAY_LEN);
|
||||
@ -200,12 +200,11 @@ public class DefaultChannelPipelineTest {
|
||||
@Test
|
||||
public void testFireChannelRegistered() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Channel ch = new LocalChannel(group.next());
|
||||
ChannelPipeline pipeline = ch.pipeline();
|
||||
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||
pipeline.addLast(new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel ch) throws Exception {
|
||||
ch.pipeline().addLast(new ChannelHandlerAdapter() {
|
||||
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
|
||||
latch.countDown();
|
||||
@ -213,13 +212,13 @@ public class DefaultChannelPipelineTest {
|
||||
});
|
||||
}
|
||||
});
|
||||
ch.unsafe().register(ch.newPromise());
|
||||
group.register(pipeline.channel());
|
||||
assertTrue(latch.await(2, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPipelineOperation() {
|
||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
||||
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||
|
||||
final int handlerNum = 5;
|
||||
ChannelHandler[] handlers1 = newHandlers(handlerNum);
|
||||
@ -247,7 +246,7 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
public void testChannelHandlerContextOrder() {
|
||||
ChannelPipeline pipeline = new LocalChannel(group.next()).pipeline();
|
||||
ChannelPipeline pipeline = new LocalChannel().pipeline();
|
||||
|
||||
pipeline.addFirst("1", newHandler());
|
||||
pipeline.addLast("10", newHandler());
|
||||
@ -444,7 +443,8 @@ public class DefaultChannelPipelineTest {
|
||||
// Tests for https://github.com/netty/netty/issues/2349
|
||||
@Test
|
||||
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();
|
||||
assertTrue(promise.cancel(false));
|
||||
@ -454,7 +454,8 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
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();
|
||||
assertTrue(promise.cancel(false));
|
||||
@ -464,7 +465,8 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
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();
|
||||
assertTrue(promise.cancel(false));
|
||||
@ -474,7 +476,8 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
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();
|
||||
assertTrue(promise.cancel(false));
|
||||
@ -482,9 +485,21 @@ public class DefaultChannelPipelineTest {
|
||||
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
|
||||
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();
|
||||
assertTrue(promise.cancel(false));
|
||||
@ -497,7 +512,8 @@ public class DefaultChannelPipelineTest {
|
||||
|
||||
@Test
|
||||
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();
|
||||
assertTrue(promise.cancel(false));
|
||||
|
@ -22,8 +22,8 @@ import java.util.EnumSet;
|
||||
final class LoggingHandler implements ChannelHandler {
|
||||
|
||||
enum Event {
|
||||
WRITE, FLUSH, BIND, CONNECT, DISCONNECT, CLOSE, READ, WRITABILITY, HANDLER_ADDED,
|
||||
HANDLER_REMOVED, EXCEPTION, READ_COMPLETE, REGISTERED, ACTIVE, INACTIVE, USER
|
||||
WRITE, FLUSH, BIND, CONNECT, DISCONNECT, CLOSE, DEREGISTER, READ, WRITABILITY, HANDLER_ADDED,
|
||||
HANDLER_REMOVED, EXCEPTION, READ_COMPLETE, REGISTERED, UNREGISTERED, ACTIVE, INACTIVE, USER
|
||||
}
|
||||
|
||||
private StringBuilder log = new StringBuilder();
|
||||
@ -68,6 +68,12 @@ final class LoggingHandler implements ChannelHandler {
|
||||
ctx.close(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregister(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
|
||||
log(Event.DEREGISTER);
|
||||
ctx.deregister(promise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ChannelHandlerContext ctx) throws Exception {
|
||||
log(Event.READ);
|
||||
@ -101,6 +107,12 @@ final class LoggingHandler implements ChannelHandler {
|
||||
ctx.fireChannelRegistered();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
|
||||
log(Event.UNREGISTERED);
|
||||
ctx.fireChannelUnregistered();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
log(Event.ACTIVE);
|
||||
|
@ -339,13 +339,11 @@ public class SingleThreadEventLoopTest {
|
||||
}
|
||||
|
||||
try {
|
||||
Channel channel = new LocalChannel(loopA);
|
||||
ChannelPromise f = channel.newPromise();
|
||||
channel.unsafe().register(f);
|
||||
ChannelFuture f = loopA.register(new LocalChannel());
|
||||
f.awaitUninterruptibly();
|
||||
assertFalse(f.isSuccess());
|
||||
assertThat(f.cause(), is(instanceOf(RejectedExecutionException.class)));
|
||||
assertFalse(channel.isOpen());
|
||||
assertFalse(f.channel().isOpen());
|
||||
} finally {
|
||||
for (Appender<ILoggingEvent> a: appenders) {
|
||||
root.addAppender(a);
|
||||
@ -358,7 +356,7 @@ public class SingleThreadEventLoopTest {
|
||||
public void testRegistrationAfterShutdown2() throws Exception {
|
||||
loopA.shutdown();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Channel ch = new LocalChannel(loopA);
|
||||
Channel ch = new LocalChannel();
|
||||
ChannelPromise promise = ch.newPromise();
|
||||
promise.addListener(new ChannelFutureListener() {
|
||||
@Override
|
||||
@ -377,10 +375,10 @@ public class SingleThreadEventLoopTest {
|
||||
}
|
||||
|
||||
try {
|
||||
ch.unsafe().register(promise);
|
||||
promise.awaitUninterruptibly();
|
||||
assertFalse(promise.isSuccess());
|
||||
assertThat(promise.cause(), is(instanceOf(RejectedExecutionException.class)));
|
||||
ChannelFuture f = loopA.register(ch, promise);
|
||||
f.awaitUninterruptibly();
|
||||
assertFalse(f.isSuccess());
|
||||
assertThat(f.cause(), is(instanceOf(RejectedExecutionException.class)));
|
||||
|
||||
// Ensure the listener was notified.
|
||||
assertFalse(latch.await(1, TimeUnit.SECONDS));
|
||||
|
@ -82,7 +82,7 @@ public class ThreadPerChannelEventLoopGroupTest {
|
||||
ChannelGroup channelGroup = new DefaultChannelGroup(testExecutor);
|
||||
while (taskCount-- > 0) {
|
||||
Channel channel = new EmbeddedChannel(NOOP_HANDLER);
|
||||
channel.unsafe().register(new DefaultChannelPromise(channel, testExecutor));
|
||||
loopGroup.register(channel, new DefaultChannelPromise(channel, testExecutor));
|
||||
channelGroup.add(channel);
|
||||
}
|
||||
channelGroup.close().sync();
|
||||
|
@ -89,7 +89,7 @@ public class LocalTransportThreadModelTest {
|
||||
ThreadNameAuditor h2 = new ThreadNameAuditor();
|
||||
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'.
|
||||
ch.pipeline().addLast(h1);
|
||||
// h2 will be always invoked by EventExecutor 'e1'.
|
||||
@ -97,9 +97,7 @@ public class LocalTransportThreadModelTest {
|
||||
// h3 will be always invoked by EventExecutor 'e2'.
|
||||
ch.pipeline().addLast(e2, h3);
|
||||
|
||||
ChannelPromise promise = ch.newPromise();
|
||||
ch.unsafe().register(promise);
|
||||
promise.sync().channel().connect(localAddr).sync();
|
||||
l.register(ch).sync().channel().connect(localAddr).sync();
|
||||
|
||||
// Fire inbound events from all possible starting points.
|
||||
ch.pipeline().fireChannelRead("1");
|
||||
@ -242,7 +240,7 @@ public class LocalTransportThreadModelTest {
|
||||
final MessageForwarder2 h5 = new MessageForwarder2();
|
||||
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
|
||||
// outbound: int -> int -> byte[4] -> int -> int -> byte[4] -> /dev/null
|
||||
@ -253,9 +251,7 @@ public class LocalTransportThreadModelTest {
|
||||
.addLast(e4, h5)
|
||||
.addLast(e5, h6);
|
||||
|
||||
ChannelPromise promise = ch.newPromise();
|
||||
ch.unsafe().register(promise);
|
||||
promise.sync().channel().connect(localAddr).sync();
|
||||
l.register(ch).sync().channel().connect(localAddr).sync();
|
||||
|
||||
final int ROUNDS = 1024;
|
||||
final int ELEMS_PER_ROUNDS = 8192;
|
||||
|
@ -130,7 +130,7 @@ public class LocalTransportThreadModelTest3 {
|
||||
final EventForwarder h5 = new EventForwarder();
|
||||
final EventRecorder h6 = new EventRecorder(events, inbound);
|
||||
|
||||
final Channel ch = new LocalChannel(l.next());
|
||||
final Channel ch = new LocalChannel();
|
||||
if (!inbound) {
|
||||
ch.config().setAutoRead(false);
|
||||
}
|
||||
@ -141,9 +141,7 @@ public class LocalTransportThreadModelTest3 {
|
||||
.addLast(e1, h5)
|
||||
.addLast(e1, "recorder", h6);
|
||||
|
||||
ChannelPromise promise = ch.newPromise();
|
||||
ch.unsafe().register(promise);
|
||||
promise.sync().channel().connect(localAddr).sync();
|
||||
l.register(ch).sync().channel().connect(localAddr).sync();
|
||||
|
||||
final LinkedList<EventType> expectedEvents = events(inbound, 8192);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user