--- jsr166/src/test/tck/JSR166TestCase.java 2015/10/04 00:30:50 1.159 +++ jsr166/src/test/tck/JSR166TestCase.java 2015/10/04 18:40:57 1.164 @@ -590,7 +590,7 @@ public class JSR166TestCase extends Test } /** - * Finds missing try { ... } finally { joinPool(e); } + * Finds missing PoolCleaners */ void checkForkJoinPoolThreadLeaks() throws InterruptedException { Thread[] survivors = new Thread[7]; @@ -749,36 +749,33 @@ public class JSR166TestCase extends Test /** * Delays, via Thread.sleep, for the given millisecond delay, but * if the sleep is shorter than specified, may re-sleep or yield - * until time elapses. + * until time elapses. Ensures that the given time, as measured + * by System.nanoTime(), has elapsed. */ static void delay(long millis) throws InterruptedException { - long startTime = System.nanoTime(); - long ns = millis * 1000 * 1000; - for (;;) { + long nanos = millis * (1000 * 1000); + final long wakeupTime = System.nanoTime() + nanos; + do { if (millis > 0L) Thread.sleep(millis); else // too short to sleep Thread.yield(); - long d = ns - (System.nanoTime() - startTime); - if (d > 0L) - millis = d / (1000 * 1000); - else - break; - } + nanos = wakeupTime - System.nanoTime(); + millis = nanos / (1000 * 1000); + } while (nanos >= 0L); } /** * Allows use of try-with-resources with per-test thread pools. */ - class PoolCleaner - implements AutoCloseable { - public final T pool; - public PoolCleaner(T pool) { this.pool = pool; } + class PoolCleaner implements AutoCloseable { + private final ExecutorService pool; + public PoolCleaner(ExecutorService pool) { this.pool = pool; } public void close() { joinPool(pool); } } - PoolCleaner cleaner(T pool) { - return new PoolCleaner(pool); + PoolCleaner cleaner(ExecutorService pool) { + return new PoolCleaner(pool); } /** @@ -813,9 +810,8 @@ public class JSR166TestCase extends Test * necessarily individually slow because they must block. */ void testInParallel(Action ... actions) { - try (PoolCleaner cleaner - = cleaner(Executors.newCachedThreadPool())) { - ExecutorService pool = cleaner.pool; + ExecutorService pool = Executors.newCachedThreadPool(); + try (PoolCleaner cleaner = cleaner(pool)) { ArrayList> futures = new ArrayList<>(actions.length); for (final Action action : actions) futures.add(pool.submit(new CheckedRunnable() { @@ -1320,11 +1316,22 @@ public class JSR166TestCase extends Test }}; } - public Runnable awaiter(final CountDownLatch latch) { - return new CheckedRunnable() { - public void realRun() throws InterruptedException { - await(latch); - }}; + class LatchAwaiter extends CheckedRunnable { + static final int NEW = 0; + static final int RUNNING = 1; + static final int DONE = 2; + final CountDownLatch latch; + int state = NEW; + LatchAwaiter(CountDownLatch latch) { this.latch = latch; } + public void realRun() throws InterruptedException { + state = 1; + await(latch); + state = 2; + } + } + + public LatchAwaiter awaiter(CountDownLatch latch) { + return new LatchAwaiter(latch); } public void await(CountDownLatch latch) {