From d56e55d51d2871beea9f788ba4ccd7213162cdfc Mon Sep 17 00:00:00 2001 From: CoNDoRip Date: Sun, 23 Mar 2014 13:09:41 +0400 Subject: [PATCH] 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. --- .../socket/nio/NioDatagramChannel.java | 33 ++++++++++++++----- .../socket/nio/NioServerSocketChannel.java | 15 ++++++--- .../channel/socket/nio/NioSocketChannel.java | 15 ++++++--- 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java b/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java index e7b0a035cd..0167b4982e 100644 --- a/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/nio/NioDatagramChannel.java @@ -62,7 +62,7 @@ public final class NioDatagramChannel extends AbstractNioMessageChannel implements io.netty.channel.socket.DatagramChannel { 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 Map> memberships = @@ -70,7 +70,7 @@ public final class NioDatagramChannel private RecvByteBufAllocator.Handle allocHandle; - private static DatagramChannel newSocket() { + private static DatagramChannel newSocket(SelectorProvider provider) { try { /** * Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in @@ -78,21 +78,21 @@ public final class NioDatagramChannel * * See #2308. */ - return SELECTOR_PROVIDER.openDatagramChannel(); + return provider.openDatagramChannel(); } catch (IOException 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) { - return newSocket(); + return newSocket(provider); } checkJavaVersion(); try { - return SELECTOR_PROVIDER.openDatagramChannel(ProtocolFamilyConverter.convert(ipFamily)); + return provider.openDatagramChannel(ProtocolFamilyConverter.convert(ipFamily)); } catch (IOException 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}. */ 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. */ 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)); } /** diff --git a/transport/src/main/java/io/netty/channel/socket/nio/NioServerSocketChannel.java b/transport/src/main/java/io/netty/channel/socket/nio/NioServerSocketChannel.java index 0de86869ea..2a21b3a71c 100644 --- a/transport/src/main/java/io/netty/channel/socket/nio/NioServerSocketChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/nio/NioServerSocketChannel.java @@ -43,11 +43,11 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel implements io.netty.channel.socket.ServerSocketChannel { 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 ServerSocketChannel newSocket() { + private static ServerSocketChannel newSocket(SelectorProvider provider) { try { /** * Use the {@link SelectorProvider} to open {@link SocketChannel} and so remove condition in @@ -55,7 +55,7 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel * * See #2308. */ - return SELECTOR_PROVIDER.openServerSocketChannel(); + return provider.openServerSocketChannel(); } catch (IOException e) { throw new ChannelException( "Failed to open a server socket.", e); @@ -68,7 +68,14 @@ public class NioServerSocketChannel extends AbstractNioMessageServerChannel * Create a new instance */ 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)); } /** diff --git a/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java b/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java index bd4b9d531b..923191a9b5 100644 --- a/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java +++ b/transport/src/main/java/io/netty/channel/socket/nio/NioSocketChannel.java @@ -44,9 +44,9 @@ import java.nio.channels.spi.SelectorProvider; public class NioSocketChannel extends AbstractNioByteChannel implements io.netty.channel.socket.SocketChannel { 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 { /** * 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 #2308. */ - return SELECTOR_PROVIDER.openSocketChannel(); + return provider.openSocketChannel(); } catch (IOException 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 */ 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)); } /**