8157543: java/nio/channels/Selector/SelectAndCancel.java fails intermittently
Reviewed-by: alanb
--- a/test/jdk/java/nio/channels/Selector/SelectAndCancel.java Wed Apr 25 18:30:38 2018 -0700
+++ b/test/jdk/java/nio/channels/Selector/SelectAndCancel.java Thu Apr 26 10:29:44 2018 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,65 +23,61 @@
/* @test
* @bug 4729342
+ * @library /test/lib
+ * @build jdk.test.lib.Utils
+ * @run main SelectAndCancel
* @summary Check for CancelledKeyException when key cancelled during select
*/
-import java.nio.channels.*;
-import java.io.IOException;
-import java.net.*;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.util.concurrent.CountDownLatch;
public class SelectAndCancel {
- static SelectionKey sk;
+ static volatile SelectionKey sk;
+ static volatile Throwable ex;
/*
* CancelledKeyException is the failure symptom of 4729342
* NOTE: The failure is timing dependent and is not always
* seen immediately when the bug is present.
*/
- public static void main(String[] args) throws Exception {
+ public static void main(String[] args) throws Throwable {
final Selector selector = Selector.open();
- final ServerSocketChannel ssc =
- ServerSocketChannel.open().bind(new InetSocketAddress(0));
- final InetSocketAddress isa =
- new InetSocketAddress(InetAddress.getLocalHost(), ssc.socket().getLocalPort());
+ final ServerSocketChannel ssc = ServerSocketChannel.open().bind(
+ new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+ final InetSocketAddress isa = (InetSocketAddress)ssc.getLocalAddress();
+ final CountDownLatch signal = new CountDownLatch(1);
// Create and start a selector in a separate thread.
- new Thread(new Runnable() {
+ Thread t = new Thread(new Runnable() {
public void run() {
try {
ssc.configureBlocking(false);
sk = ssc.register(selector, SelectionKey.OP_ACCEPT);
+ signal.countDown();
selector.select();
- } catch (IOException e) {
- System.err.println("error in selecting thread");
- e.printStackTrace();
+ } catch (Throwable e) {
+ ex = e;
}
}
- }).start();
+ });
+ t.start();
- // Wait for above thread to get to select() before we call close.
- Thread.sleep(3000);
+ signal.await();
+ // Wait for above thread to get to select() before we call cancel.
+ Thread.sleep((long)(300 * jdk.test.lib.Utils.TIMEOUT_FACTOR));
- // Try to close. This should wakeup select.
- new Thread(new Runnable() {
- public void run() {
- try {
- SocketChannel sc = SocketChannel.open();
- sc.connect(isa);
- ssc.close();
- sk.cancel();
- sc.close();
- } catch (IOException e) {
- System.err.println("error in closing thread");
- System.err.println(e);
- }
- }
- }).start();
-
- // Wait for select() to be awakened, which should be done by close.
- Thread.sleep(3000);
-
- selector.wakeup();
+ // CancelledKeyException should not be thrown.
+ ssc.close();
+ sk.cancel();
selector.close();
+ t.join();
+ if (ex != null) {
+ throw ex;
+ }
}
}