8157543: java/nio/channels/Selector/SelectAndCancel.java fails intermittently jdk-11+11
authormli
Thu, 26 Apr 2018 10:29:44 +0800
changeset 49893 e1e60f75cd39
parent 49892 8bed781a8d9c
child 49894 c830e94b5606
8157543: java/nio/channels/Selector/SelectAndCancel.java fails intermittently Reviewed-by: alanb
test/jdk/java/nio/channels/Selector/SelectAndCancel.java
--- 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;
+        }
     }
 }