mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-15 21:05:11 +00:00
8027212: java/nio/channels/Selector/SelectAfterRead.java fails intermittently
Reviewed-by: chegar, ewang
This commit is contained in:
parent
997e4bbc8b
commit
91cc7f3c28
@ -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;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.io.IOException;
|
||||
import java.io.Closeable;
|
||||
|
||||
public class ByteServer {
|
||||
public class ByteServer implements Closeable {
|
||||
|
||||
public static final String LOCALHOST = "localhost";
|
||||
private int bytecount;
|
||||
private Socket socket;
|
||||
private ServerSocket serversocket;
|
||||
private Thread serverthread;
|
||||
volatile Exception savedException;
|
||||
private final ServerSocket ss;
|
||||
private Socket s;
|
||||
|
||||
public ByteServer(int bytecount) throws Exception{
|
||||
this.bytecount = bytecount;
|
||||
serversocket = new ServerSocket(0);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
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();
|
||||
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_READ);
|
||||
// Previously channel would get selected here, although there is nothing to read
|
||||
if (sel.selectNow() != 0)
|
||||
throw new Exception("Select returned nonzero value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user