Allow specifying SelectorProvider when constructing an NIO channel #2311

Motivation:

At the moment we use the system-wide default selector provider for this invocation of the Java virtual machine when constructing a new NIO channel, which makes using an alternative SelectorProvider practically useless.
This change allows user specify his/her preferred SelectorProvider.

Modifications:

Add SelectorProvider as a param for current `private static *Channel newSocket` method of NioSocketChannel, NioServerSocketChannel and NioDatagramChannel.
Change default constructors of NioSocketChannel, NioServerSocketChannel and NioDatagramChannel to use DEFAULT_SELECTOR_PROVIDER when calling newSocket(SelectorProvider).
Add new constructors for NioSocketChannel, NioServerSocketChannel and NioDatagramChannel which allow user specify his/her preferred SelectorProvider.

Result:

Now users can specify his/her preferred SelectorProvider when constructing an NIO channel.
This commit is contained in:
CoNDoRip 2014-03-23 13:09:41 +04:00 committed by Norman Maurer
parent 460b0892bb
commit d56e55d51d
3 changed files with 47 additions and 16 deletions

View File

@ -62,7 +62,7 @@ public final class NioDatagramChannel
extends AbstractNioMessageChannel implements io.netty.channel.socket.DatagramChannel { extends AbstractNioMessageChannel implements io.netty.channel.socket.DatagramChannel {
private static final ChannelMetadata METADATA = new ChannelMetadata(true); private static final ChannelMetadata METADATA = new ChannelMetadata(true);
private static final SelectorProvider SELECTOR_PROVIDER = SelectorProvider.provider(); private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
private final DatagramChannelConfig config; private final DatagramChannelConfig config;
private final Map<InetAddress, List<MembershipKey>> memberships = private final Map<InetAddress, List<MembershipKey>> memberships =
@ -70,7 +70,7 @@ public final class NioDatagramChannel
private RecvByteBufAllocator.Handle allocHandle; private RecvByteBufAllocator.Handle allocHandle;
private static DatagramChannel newSocket() { private static DatagramChannel newSocket(SelectorProvider provider) {
try { try {
/** /**
* Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in * Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in
@ -78,21 +78,21 @@ public final class NioDatagramChannel
* *
* See <a href="See https://github.com/netty/netty/issues/2308">#2308</a>. * See <a href="See https://github.com/netty/netty/issues/2308">#2308</a>.
*/ */
return SELECTOR_PROVIDER.openDatagramChannel(); return provider.openDatagramChannel();
} catch (IOException e) { } catch (IOException e) {
throw new ChannelException("Failed to open a socket.", e); throw new ChannelException("Failed to open a socket.", e);
} }
} }
private static DatagramChannel newSocket(InternetProtocolFamily ipFamily) { private static DatagramChannel newSocket(SelectorProvider provider, InternetProtocolFamily ipFamily) {
if (ipFamily == null) { if (ipFamily == null) {
return newSocket(); return newSocket(provider);
} }
checkJavaVersion(); checkJavaVersion();
try { try {
return SELECTOR_PROVIDER.openDatagramChannel(ProtocolFamilyConverter.convert(ipFamily)); return provider.openDatagramChannel(ProtocolFamilyConverter.convert(ipFamily));
} catch (IOException e) { } catch (IOException e) {
throw new ChannelException("Failed to open a socket.", e); throw new ChannelException("Failed to open a socket.", e);
} }
@ -108,7 +108,15 @@ public final class NioDatagramChannel
* Create a new instance which will use the Operation Systems default {@link InternetProtocolFamily}. * Create a new instance which will use the Operation Systems default {@link InternetProtocolFamily}.
*/ */
public NioDatagramChannel(EventLoop eventLoop) { public NioDatagramChannel(EventLoop eventLoop) {
this(eventLoop, newSocket()); 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));
} }
/** /**
@ -116,7 +124,16 @@ public final class NioDatagramChannel
* on the Operation Systems default which will be chosen. * on the Operation Systems default which will be chosen.
*/ */
public NioDatagramChannel(EventLoop eventLoop, InternetProtocolFamily ipFamily) { public NioDatagramChannel(EventLoop eventLoop, InternetProtocolFamily ipFamily) {
this(eventLoop, newSocket(ipFamily)); this(eventLoop, newSocket(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));
} }
/** /**

View File

@ -43,11 +43,11 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel
implements io.netty.channel.socket.ServerSocketChannel { implements io.netty.channel.socket.ServerSocketChannel {
private static final ChannelMetadata METADATA = new ChannelMetadata(false); private static final ChannelMetadata METADATA = new ChannelMetadata(false);
private static final SelectorProvider SELECTOR_PROVIDER = SelectorProvider.provider(); private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioServerSocketChannel.class); private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioServerSocketChannel.class);
private static ServerSocketChannel newSocket() { private static ServerSocketChannel newSocket(SelectorProvider provider) {
try { try {
/** /**
* Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in * Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in
@ -55,7 +55,7 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel
* *
* See <a href="See https://github.com/netty/netty/issues/2308">#2308</a>. * See <a href="See https://github.com/netty/netty/issues/2308">#2308</a>.
*/ */
return SELECTOR_PROVIDER.openServerSocketChannel(); return provider.openServerSocketChannel();
} catch (IOException e) { } catch (IOException e) {
throw new ChannelException( throw new ChannelException(
"Failed to open a server socket.", e); "Failed to open a server socket.", e);
@ -68,7 +68,14 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel
* Create a new instance * Create a new instance
*/ */
public NioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) { public NioServerSocketChannel(EventLoop eventLoop, EventLoopGroup childGroup) {
this(eventLoop, childGroup, newSocket()); this(eventLoop, childGroup, newSocket(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));
} }
/** /**

View File

@ -44,9 +44,9 @@ import java.nio.channels.spi.SelectorProvider;
public class NioSocketChannel extends AbstractNioByteChannel implements io.netty.channel.socket.SocketChannel { public class NioSocketChannel extends AbstractNioByteChannel implements io.netty.channel.socket.SocketChannel {
private static final ChannelMetadata METADATA = new ChannelMetadata(false); private static final ChannelMetadata METADATA = new ChannelMetadata(false);
private static final SelectorProvider SELECTOR_PROVIDER = SelectorProvider.provider(); private static final SelectorProvider DEFAULT_SELECTOR_PROVIDER = SelectorProvider.provider();
private static SocketChannel newSocket() { private static SocketChannel newSocket(SelectorProvider provider) {
try { try {
/** /**
* Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in * Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in
@ -54,7 +54,7 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
* *
* See <a href="See https://github.com/netty/netty/issues/2308">#2308</a>. * See <a href="See https://github.com/netty/netty/issues/2308">#2308</a>.
*/ */
return SELECTOR_PROVIDER.openSocketChannel(); return provider.openSocketChannel();
} catch (IOException e) { } catch (IOException e) {
throw new ChannelException("Failed to open a socket.", e); throw new ChannelException("Failed to open a socket.", e);
} }
@ -66,7 +66,14 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
* Create a new instance * Create a new instance
*/ */
public NioSocketChannel(EventLoop eventLoop) { public NioSocketChannel(EventLoop eventLoop) {
this(eventLoop, newSocket()); this(eventLoop, newSocket(DEFAULT_SELECTOR_PROVIDER));
}
/**
* Create a new instance using the given {@link SelectorProvider}.
*/
public NioSocketChannel(EventLoop eventLoop, SelectorProvider provider) {
this(eventLoop, newSocket(provider));
} }
/** /**