Fix SelectableChannel support in NioEventLoop (#8344)
Motivation: Unless the 'io.netty.noKeySetOptimization' system property is set, registering a SelectableChannel instance to a NioEventLoop results in a ClassCastException: io.netty.channel.nio.SelectedSelectionKeySetSelector cannot be cast to java.nio.channels.spi.AbstractSelector Modifications: Instead of 'selector', pass 'unwrappedSelector' to SelectableChannel. Result: It is possible to register a SelectableChannel instance without setting the 'io.netty.noKeySetOptimization' system property.
This commit is contained in:
parent
6cebb6069b
commit
fc28bccdf1
@ -294,7 +294,7 @@ public final class NioEventLoop extends SingleThreadEventLoop {
|
||||
}
|
||||
|
||||
try {
|
||||
ch.register(selector, interestOps, task);
|
||||
ch.register(unwrappedSelector, interestOps, task);
|
||||
} catch (Exception e) {
|
||||
throw new EventLoopException("failed to register a channel", e);
|
||||
}
|
||||
|
@ -24,7 +24,10 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -132,4 +135,40 @@ public class NioEventLoopTest extends AbstractEventLoopTest {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 1000)
|
||||
public void testSelectableChannel() throws Exception {
|
||||
NioEventLoopGroup group = new NioEventLoopGroup(1);
|
||||
NioEventLoop loop = (NioEventLoop) group.next();
|
||||
|
||||
try {
|
||||
Channel channel = new NioServerSocketChannel();
|
||||
loop.register(channel).syncUninterruptibly();
|
||||
channel.bind(new InetSocketAddress(0)).syncUninterruptibly();
|
||||
|
||||
SocketChannel selectableChannel = SocketChannel.open();
|
||||
selectableChannel.configureBlocking(false);
|
||||
selectableChannel.connect(channel.localAddress());
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
loop.register(selectableChannel, SelectionKey.OP_CONNECT, new NioTask<SocketChannel>() {
|
||||
@Override
|
||||
public void channelReady(SocketChannel ch, SelectionKey key) {
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelUnregistered(SocketChannel ch, Throwable cause) {
|
||||
}
|
||||
});
|
||||
|
||||
latch.await();
|
||||
|
||||
selectableChannel.close();
|
||||
channel.close().syncUninterruptibly();
|
||||
} finally {
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user