8161991: java/nio/channels/AsynchronousSocketChannel/Basic.java failed due to RuntimeException: WritePendingException expected

8171404: java/nio/channels/AsynchronousSocketChannel/Basic.java failed with "AsynchronousCloseException expected"
8201520: AsynchronousSocketChannel/Basic.java timeout intermitently

Reviewed-by: alanb
This commit is contained in:
Hamlin Li 2018-04-20 15:16:36 +08:00
parent 97c2167e1c
commit 17da4aca08

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,8 @@
* @bug 4607272 6842687 6878369 6944810 7023403 * @bug 4607272 6842687 6878369 6944810 7023403
* @summary Unit test for AsynchronousSocketChannel(use -Dseed=X to set PRNG seed) * @summary Unit test for AsynchronousSocketChannel(use -Dseed=X to set PRNG seed)
* @library /test/lib * @library /test/lib
* @build jdk.test.lib.RandomFactory * @build jdk.test.lib.RandomFactory jdk.test.lib.Utils
* @run main Basic -skipSlowConnectTest * @run main/othervm/timeout=600 Basic -skipSlowConnectTest
* @key randomness intermittent * @key randomness intermittent
*/ */
@ -79,11 +79,16 @@ public class Basic {
private final InetSocketAddress address; private final InetSocketAddress address;
Server() throws IOException { Server() throws IOException {
ssc = ServerSocketChannel.open().bind(new InetSocketAddress(0)); this(0);
}
InetAddress lh = InetAddress.getLocalHost(); Server(int recvBufSize) throws IOException {
int port = ((InetSocketAddress)(ssc.getLocalAddress())).getPort(); ssc = ServerSocketChannel.open();
address = new InetSocketAddress(lh, port); if (recvBufSize > 0) {
ssc.setOption(SO_RCVBUF, recvBufSize);
}
ssc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
address = (InetSocketAddress)ssc.getLocalAddress();
} }
InetSocketAddress address() { InetSocketAddress address() {
@ -293,7 +298,7 @@ public class Basic {
System.out.println("-- asynchronous close when reading --"); System.out.println("-- asynchronous close when reading --");
try (Server server = new Server()) { try (Server server = new Server(1)) {
ch = AsynchronousSocketChannel.open(); ch = AsynchronousSocketChannel.open();
ch.connect(server.address()).get(); ch.connect(server.address()).get();
@ -325,6 +330,8 @@ public class Basic {
ch = AsynchronousSocketChannel.open(); ch = AsynchronousSocketChannel.open();
ch.connect(server.address()).get(); ch.connect(server.address()).get();
SocketChannel peer = server.accept();
peer.setOption(SO_RCVBUF, 1);
final AtomicReference<Throwable> writeException = final AtomicReference<Throwable> writeException =
new AtomicReference<Throwable>(); new AtomicReference<Throwable>();
@ -333,10 +340,13 @@ public class Basic {
final AtomicInteger numCompleted = new AtomicInteger(); final AtomicInteger numCompleted = new AtomicInteger();
ch.write(genBuffer(), ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() { ch.write(genBuffer(), ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
public void completed(Integer result, AsynchronousSocketChannel ch) { public void completed(Integer result, AsynchronousSocketChannel ch) {
System.out.println("completed write to async channel: " + result);
numCompleted.incrementAndGet(); numCompleted.incrementAndGet();
ch.write(genBuffer(), ch, this); ch.write(genBuffer(), ch, this);
System.out.println("started another write to async channel: " + result);
} }
public void failed(Throwable x, AsynchronousSocketChannel ch) { public void failed(Throwable x, AsynchronousSocketChannel ch) {
System.out.println("failed write to async channel");
writeException.set(x); writeException.set(x);
} }
}); });
@ -347,7 +357,8 @@ public class Basic {
// the internal channel state indicates it is writing // the internal channel state indicates it is writing
int prevNumCompleted = numCompleted.get(); int prevNumCompleted = numCompleted.get();
do { do {
Thread.sleep(1000); Thread.sleep((long)(1000 * jdk.test.lib.Utils.TIMEOUT_FACTOR));
System.out.println("check if buffer is filled up");
if (numCompleted.get() == prevNumCompleted) { if (numCompleted.get() == prevNumCompleted) {
break; break;
} }
@ -357,14 +368,19 @@ public class Basic {
// attempt a concurrent write - // attempt a concurrent write -
// should fail with WritePendingException // should fail with WritePendingException
try { try {
System.out.println("concurrent write to async channel");
ch.write(genBuffer()); ch.write(genBuffer());
System.out.format("prevNumCompleted: %d, numCompleted: %d%n",
prevNumCompleted, numCompleted.get());
throw new RuntimeException("WritePendingException expected"); throw new RuntimeException("WritePendingException expected");
} catch (WritePendingException x) { } catch (WritePendingException x) {
} }
// close channel - should cause initial write to complete // close channel - should cause initial write to complete
System.out.println("closing async channel...");
ch.close(); ch.close();
server.accept().close(); System.out.println("closed async channel");
peer.close();
// wait for exception // wait for exception
while (writeException.get() == null) { while (writeException.get() == null) {