提交 6aff2fdc 编写于 作者: I igerasim

8027212: java/nio/channels/Selector/SelectAfterRead.java fails intermittently

Reviewed-by: chegar, ewang
上级 0a6671b5
......@@ -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 implements Closeable {
public class ByteServer {
private final ServerSocket ss;
private Socket s;
public static final String LOCALHOST = "localhost";
private int bytecount;
private Socket socket;
private ServerSocket serversocket;
private Thread serverthread;
volatile Exception savedException;
ByteServer() throws IOException {
this.ss = new ServerSocket(0);
}
SocketAddress address() {
return new InetSocketAddress(ss.getInetAddress(), ss.getLocalPort());
}
public ByteServer(int bytecount) throws Exception{
this.bytecount = bytecount;
serversocket = new ServerSocket(0);
void acceptConnection() throws IOException {
if (s != null)
throw new IllegalStateException("already connected");
this.s = ss.accept();
}
public int port() {
return serversocket.getLocalPort();
void closeConnection() throws IOException {
Socket s = this.s;
if (s != null) {
this.s = null;
s.close();
}
}
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 write(int count) throws IOException {
if (s == null)
throw new IllegalStateException("no connection");
s.getOutputStream().write(new byte[count]);
}
public void exit() throws Exception {
serverthread.join();
socket.close();
serversocket.close();
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();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册