8079773: java/util/logging/LogManager/TestLoggerNames.java
authordfuchs
Tue, 12 May 2015 14:32:50 +0200
changeset 30442 bb6b137056e4
parent 30441 415a5242e046
child 30443 8d2f2ce637bd
8079773: java/util/logging/LogManager/TestLoggerNames.java Summary: Fixed a race condition in the test which was responsible of the intermittent failure. Reviewed-by: mchung
jdk/test/java/util/logging/LogManager/TestLoggerNames.java
--- a/jdk/test/java/util/logging/LogManager/TestLoggerNames.java	Tue May 12 10:50:40 2015 +0200
+++ b/jdk/test/java/util/logging/LogManager/TestLoggerNames.java	Tue May 12 14:32:50 2015 +0200
@@ -20,6 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Iterator;
@@ -107,7 +108,11 @@
                     System.out.println("OK: Iterator doesn't support remove.");
                 }
             }
+            // We're not supposed to come here, but if we do then we
+            // need to rewind names...
+            names = LogManager.getLogManager().getLoggerNames();
         }
+
         List<String> loggerNames = Collections.list(names);
         if (!loggerNames.contains("")) {
             throw new RuntimeException("\"\"" +
@@ -147,7 +152,13 @@
         Thread loggerNamesThread = new Thread(() -> {
             try {
                 while (!stop) {
-                    checkLoggerNames(loggers);
+                    // Make a defensive copy of the list of loggers that we pass
+                    // to checkLoggerNames - in order to make sure that
+                    // we won't see new loggers that might appear after
+                    // checkLoggerNames has called LogManager.getLoggerNames().
+                    // ('loggers' is a live list and the main thread adds and
+                    //  and removes loggers from it concurrently to this thread).
+                    checkLoggerNames(new ArrayList<>(loggers));
                     Thread.sleep(10);
                     if (!stop) {
                         phaser.arriveAndAwaitAdvance();
@@ -156,6 +167,10 @@
             } catch (Throwable t) {
                 t.printStackTrace(System.err);
                 checkLoggerNamesFailed = t;
+                // makes sure the main thread isn't going to wait
+                // forever waiting for this dead thread to arrive at the
+                // phaser.
+                phaser.arrive();
             }
         }, "loggerNames");
 
@@ -197,14 +212,29 @@
                     loggers.remove(l);
                     l = Logger.getLogger(name.replace("replaceMe", "meReplaced"));
                     loggers.add(l);
+                    // Give some chance to the loggerNames thread to arrive at the
+                    // phaser first. We don't really care if the logger is actually
+                    // replaced this turn - or the next.
+                    Thread.sleep(100);
                     System.gc();
                     if (LogManager.getLogManager().getLogger(name) == null) {
-                        System.out.println("*** "+ name + " successfully replaced with " + l.getName());
+                        // The original logger may not have been gc'ed yet, since
+                        // it could still be referenced by the list being processed
+                        // by the loggerNamesThread, if that thread hasn't arrived
+                        // to the phaser yet...
+                        System.out.println("*** "+ name
+                                + " successfully replaced with " + l.getName());
                     }
                     i++;
                 } else {
                     System.out.println("Nothing to do for logger: " + name);
                 }
+                if (checkLoggerNamesFailed != null) {
+                    // The checkLoggerNames thread failed. No need to
+                    // continue.
+                    break;
+                }
+                // Waits for the checkLoggerNamesThread to arrive
                 phaser.arriveAndAwaitAdvance();
                 if (i >= 3 && i++ == 3) {
                     System.out.println("Loggers are now: " +