# HG changeset patch # User igerasim # Date 1392897695 -14400 # Node ID 550daf7361efab11d090d644626ba153f00c11f4 # Parent 40b6578cddccd46bafc160fe8ae08a63ee8a5996 8027212: java/nio/channels/Selector/SelectAfterRead.java fails intermittently Reviewed-by: chegar, ewang diff -r 40b6578cddcc -r 550daf7361ef test/java/nio/channels/Selector/ByteServer.java --- a/test/java/nio/channels/Selector/ByteServer.java Thu Apr 10 13:55:57 2014 +0400 +++ b/test/java/nio/channels/Selector/ByteServer.java Thu Feb 20 16:01:35 2014 +0400 @@ -22,52 +22,54 @@ */ /** - * - * Utility class for tests. A simple server, which waits for a connection, - * writes out n bytes and waits. + * Utility class for tests. A simple "in-thread" server to accept connections + * and write bytes. * @author kladko */ import java.net.Socket; import java.net.ServerSocket; - -public class ByteServer { +import java.net.SocketAddress; +import java.net.InetSocketAddress; +import java.io.IOException; +import java.io.Closeable; - public static final String LOCALHOST = "localhost"; - private int bytecount; - private Socket socket; - private ServerSocket serversocket; - private Thread serverthread; - volatile Exception savedException; +public class ByteServer implements Closeable { - public ByteServer(int bytecount) throws Exception{ - this.bytecount = bytecount; - serversocket = new ServerSocket(0); + private final ServerSocket ss; + private Socket s; + + ByteServer() throws IOException { + this.ss = new ServerSocket(0); } - public int port() { - return serversocket.getLocalPort(); + SocketAddress address() { + return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort()); } - public void start() { - serverthread = new Thread() { - public void run() { - try { - socket = serversocket.accept(); - socket.getOutputStream().write(new byte[bytecount]); - socket.getOutputStream().flush(); - } catch (Exception e) { - System.err.println("Exception in ByteServer: " + e); - System.exit(1); - } - } - }; - serverthread.start(); + void acceptConnection() throws IOException { + if (s != null) + throw new IllegalStateException("already connected"); + this.s = ss.accept(); } - public void exit() throws Exception { - serverthread.join(); - socket.close(); - serversocket.close(); + void closeConnection() throws IOException { + Socket s = this.s; + if (s != null) { + this.s = null; + s.close(); + } + } + + void write(int count) throws IOException { + if (s == null) + throw new IllegalStateException("no connection"); + s.getOutputStream().write(new byte[count]); + } + + public void close() throws IOException { + if (s != null) + s.close(); + ss.close(); } } diff -r 40b6578cddcc -r 550daf7361ef test/java/nio/channels/Selector/ReadAfterConnect.java --- a/test/java/nio/channels/Selector/ReadAfterConnect.java Thu Apr 10 13:55:57 2014 +0400 +++ b/test/java/nio/channels/Selector/ReadAfterConnect.java Thu Feb 20 16:01:35 2014 +0400 @@ -27,27 +27,25 @@ * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class ReadAfterConnect { + public static void main(String[] argv) throws Exception { + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { - public static void main(String[] argv) throws Exception { - ByteServer server = new ByteServer(0); // server: accept connection and do nothing - server.start(); - InetSocketAddress isa = new InetSocketAddress( - InetAddress.getByName(ByteServer.LOCALHOST), server.port()); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(isa); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_READ); - // Previously channel would get selected here, although there is nothing to read - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - server.exit(); + server.acceptConnection(); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + // Previously channel would get selected here, although there is nothing to read + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } } } diff -r 40b6578cddcc -r 550daf7361ef test/java/nio/channels/Selector/SelectAfterRead.java --- a/test/java/nio/channels/Selector/SelectAfterRead.java Thu Apr 10 13:55:57 2014 +0400 +++ b/test/java/nio/channels/Selector/SelectAfterRead.java Thu Feb 20 16:01:35 2014 +0400 @@ -28,60 +28,62 @@ * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; +import java.nio.ByteBuffer; +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class SelectAfterRead { - final static int TIMEOUT = 1000; + private static final int TIMEOUT = 1000; public static void main(String[] argv) throws Exception { - InetAddress lh = InetAddress.getByName(ByteServer.LOCALHOST); // server: accept connection and write one byte - ByteServer server = new ByteServer(1); - server.start(); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(new InetSocketAddress(lh, server.port())); - sc.read(ByteBuffer.allocate(1)); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_READ); - // previously on Windows select would select channel here, although there was - // nothing to read - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - sel.close(); - server.exit(); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + server.write(1); + + try (Selector sel = Selector.open()) { + sc.read(ByteBuffer.allocate(1)); + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + // previously on Windows select would select channel here, although there was + // nothing to read + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } // Now we will test a two reads combination // server: accept connection and write two bytes - server = new ByteServer(2); - server.start(); - sc = SocketChannel.open(); - sc.connect(new InetSocketAddress(lh, server.port())); - sc.configureBlocking(false); - sel = Selector.open(); - sc.register(sel, SelectionKey.OP_READ); - if (sel.select(TIMEOUT) != 1) - throw new Exception("One selected key expected"); - sel.selectedKeys().clear(); - // previously on Windows a channel would get selected only once - if (sel.selectNow() != 1) - throw new Exception("One selected key expected"); - // Previously on Windows two consequent reads would cause select() - // to select a channel, although there was nothing remaining to - // read in the channel - if (sc.read(ByteBuffer.allocate(1)) != 1) - throw new Exception("One byte expected"); - if (sc.read(ByteBuffer.allocate(1)) != 1) - throw new Exception("One byte expected"); - if (sel.selectNow() != 0) - throw new Exception("Select returned nonzero value"); - sc.close(); - sel.close(); - server.exit(); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + server.write(2); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_READ); + if (sel.select(TIMEOUT) != 1) + throw new Exception("One selected key expected"); + sel.selectedKeys().clear(); + // previously on Windows a channel would get selected only once + if (sel.selectNow() != 1) + throw new Exception("One selected key expected"); + // Previously on Windows two consequent reads would cause select() + // to select a channel, although there was nothing remaining to + // read in the channel + if (sc.read(ByteBuffer.allocate(1)) != 1) + throw new Exception("One byte expected"); + if (sc.read(ByteBuffer.allocate(1)) != 1) + throw new Exception("One byte expected"); + if (sel.selectNow() != 0) + throw new Exception("Select returned nonzero value"); + } + } } } diff -r 40b6578cddcc -r 550daf7361ef test/java/nio/channels/Selector/SelectWrite.java --- a/test/java/nio/channels/Selector/SelectWrite.java Thu Apr 10 13:55:57 2014 +0400 +++ b/test/java/nio/channels/Selector/SelectWrite.java Thu Feb 20 16:01:35 2014 +0400 @@ -22,36 +22,33 @@ */ /* @test - @bug 4645302 - @summary Socket with OP_WRITE would get selected only once - @author kladko + * @bug 4645302 + * @summary Socket with OP_WRITE would get selected only once + * @author kladko */ -import java.net.*; -import java.nio.*; -import java.nio.channels.*; - +import java.nio.channels.Selector; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; public class SelectWrite { public static void main(String[] argv) throws Exception { - ByteServer server = new ByteServer(0); - // server: accept connection and do nothing - server.start(); - InetSocketAddress isa = new InetSocketAddress( - InetAddress.getByName(ByteServer.LOCALHOST), server.port()); - Selector sel = Selector.open(); - SocketChannel sc = SocketChannel.open(); - sc.connect(isa); - sc.configureBlocking(false); - sc.register(sel, SelectionKey.OP_WRITE); - sel.select(); - sel.selectedKeys().clear(); - if (sel.select() == 0) { - throw new Exception("Select returned zero"); + try (ByteServer server = new ByteServer(); + SocketChannel sc = SocketChannel.open(server.address())) { + + server.acceptConnection(); + + try (Selector sel = Selector.open()) { + sc.configureBlocking(false); + sc.register(sel, SelectionKey.OP_WRITE); + sel.select(); + sel.selectedKeys().clear(); + if (sel.select() == 0) { + throw new Exception("Select returned zero"); + } + } } - sc.close(); - sel.close(); } }