8012237: CompletableFuture/Basic.java still fails intermittently
authorchegar
Tue, 16 Apr 2013 12:51:22 +0100
changeset 16865 e443e809a4ab
parent 16864 e3d9b9cf6d3c
child 16866 e659009ee08d
8012237: CompletableFuture/Basic.java still fails intermittently Reviewed-by: martin
jdk/test/java/util/concurrent/CompletableFuture/Basic.java
--- a/jdk/test/java/util/concurrent/CompletableFuture/Basic.java	Tue Apr 16 12:23:16 2013 +0100
+++ b/jdk/test/java/util/concurrent/CompletableFuture/Basic.java	Tue Apr 16 12:51:22 2013 +0100
@@ -504,7 +504,7 @@
             cf1 = supplyAsync(() -> { throw new RuntimeException(); });
             cf2 = supplyAsync(() -> 2);
             cf3 = cf1.applyToEither(cf2, (x) -> { check(x == 2); return x; });
-            try { check(cf3.join() == 1); } catch (CompletionException x) { pass(); }
+            try { check(cf3.join() == 2); } catch (CompletionException x) { pass(); }
             check(cf3.isDone());
             check(cf1.isDone() || cf2.isDone());
 
@@ -520,6 +520,27 @@
             cf3 = cf1.applyToEitherAsync(cf2, (x) -> { fail(); return x; });
             checkCompletedExceptionally(cf3);
             check(cf1.isDone() || cf2.isDone());
+
+            final Phaser cf3Done = new Phaser(2);
+            cf1 = supplyAsync(() -> { cf3Done.arriveAndAwaitAdvance(); return 1; });
+            cf2 = supplyAsync(() -> 2);
+            cf3 = cf1.applyToEither(cf2, (x) -> { check(x == 2); return x; });
+            checkCompletedNormally(cf3, 2);
+            checkCompletedNormally(cf2, 2);
+            check(!cf1.isDone());
+            cf3Done.arrive();
+            checkCompletedNormally(cf1, 1);
+            checkCompletedNormally(cf3, 2);
+
+            cf1 = supplyAsync(() -> 1);
+            cf2 = supplyAsync(() -> { cf3Done.arriveAndAwaitAdvance(); return 2; });
+            cf3 = cf1.applyToEitherAsync(cf2, (x) -> { check(x == 1); return x; });
+            checkCompletedNormally(cf3, 1);
+            checkCompletedNormally(cf1, 1);
+            check(!cf2.isDone());
+            cf3Done.arrive();
+            checkCompletedNormally(cf2, 2);
+            checkCompletedNormally(cf3, 1);
         } catch (Throwable t) { unexpected(t); }
 
         //----------------------------------------------------------------
@@ -570,6 +591,27 @@
             cf3 = cf2.acceptEitherAsync(cf1, (x) -> { fail(); });
             checkCompletedExceptionally(cf3);
             check(cf1.isDone() || cf2.isDone());
+
+            final Phaser cf3Done = new Phaser(2);
+            cf1 = supplyAsync(() -> { cf3Done.arriveAndAwaitAdvance(); return 1; });
+            cf2 = supplyAsync(() -> 2);
+            cf3 = cf1.acceptEither(cf2, (x) -> { check(x == 2); });
+            checkCompletedNormally(cf3, null);
+            checkCompletedNormally(cf2, 2);
+            check(!cf1.isDone());
+            cf3Done.arrive();
+            checkCompletedNormally(cf1, 1);
+            checkCompletedNormally(cf3, null);
+
+            cf1 = supplyAsync(() -> 1);
+            cf2 = supplyAsync(() -> { cf3Done.arriveAndAwaitAdvance(); return 2; });
+            cf3 = cf1.acceptEitherAsync(cf2, (x) -> { check(x == 1); });
+            checkCompletedNormally(cf3, null);
+            checkCompletedNormally(cf1, 1);
+            check(!cf2.isDone());
+            cf3Done.arrive();
+            checkCompletedNormally(cf2, 2);
+            checkCompletedNormally(cf3, null);
         } catch (Throwable t) { unexpected(t); }
 
         //----------------------------------------------------------------
@@ -605,19 +647,23 @@
             cf1 = runAsync(() -> { throw new RuntimeException(); });
             cf2 = runAsync(() -> { });
             cf3 = cf2.runAfterEither(cf1, () -> { atomicInt.incrementAndGet(); });
-            try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
+            try {
+                check(cf3.join() == null);
+                check(atomicInt.get() == (before + 1));
+            } catch (CompletionException x) { pass(); }
             check(cf3.isDone());
             check(cf1.isDone() || cf2.isDone());
-            check(atomicInt.get() == (before + 1));
 
             before = atomicInt.get();
             cf1 = runAsync(() -> { });
             cf2 = runAsync(() -> { throw new RuntimeException(); });
             cf3 = cf1.runAfterEitherAsync(cf2, () -> { atomicInt.incrementAndGet(); });
-            try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
+            try {
+                check(cf3.join() == null);
+                check(atomicInt.get() == (before + 1));
+            } catch (CompletionException x) { pass(); }
             check(cf3.isDone());
             check(cf1.isDone() || cf2.isDone());
-            check(atomicInt.get() == (before + 1));
 
             before = atomicInt.get();
             cf1 = runAsync(() -> { throw new RuntimeException(); });
@@ -626,6 +672,31 @@
             checkCompletedExceptionally(cf3);
             check(cf1.isDone() || cf2.isDone());
             check(atomicInt.get() == before);
+
+            final Phaser cf3Done = new Phaser(2);
+            before = atomicInt.get();
+            cf1 = runAsync(() -> { cf3Done.arriveAndAwaitAdvance(); });
+            cf2 = runAsync(() -> { });
+            cf3 = cf1.runAfterEither(cf2, () -> { atomicInt.incrementAndGet(); });
+            checkCompletedNormally(cf3, null);
+            checkCompletedNormally(cf2, null);
+            check(!cf1.isDone());
+            check(atomicInt.get() == (before + 1));
+            cf3Done.arrive();
+            checkCompletedNormally(cf1, null);
+            checkCompletedNormally(cf3, null);
+
+            before = atomicInt.get();
+            cf1 = runAsync(() -> { });
+            cf2 = runAsync(() -> { cf3Done.arriveAndAwaitAdvance(); });
+            cf3 = cf1.runAfterEitherAsync(cf2, () -> { atomicInt.incrementAndGet(); });
+            checkCompletedNormally(cf3, null);
+            checkCompletedNormally(cf1, null);
+            check(!cf2.isDone());
+            check(atomicInt.get() == (before + 1));
+            cf3Done.arrive();
+            checkCompletedNormally(cf2, null);
+            checkCompletedNormally(cf3, null);
         } catch (Throwable t) { unexpected(t); }
 
         //----------------------------------------------------------------