--- jsr166/src/jsr166e/CompletableFuture.java 2013/01/02 14:13:12 1.1 +++ jsr166/src/jsr166e/CompletableFuture.java 2013/01/02 18:20:16 1.3 @@ -403,7 +403,7 @@ public class CompletableFuture implem } public final boolean exec() { CompletableFuture d; Throwable ex; - if ((d = this.dst) != null) { + if ((d = this.dst) != null && d.result == null) { try { fn.run(); ex = null; @@ -425,7 +425,7 @@ public class CompletableFuture implem } public final boolean exec() { CompletableFuture d; U u; Throwable ex; - if ((d = this.dst) != null) { + if ((d = this.dst) != null && d.result == null) { try { u = fn.get(); ex = null; @@ -450,7 +450,7 @@ public class CompletableFuture implem } public final boolean exec() { CompletableFuture d; U u; Throwable ex; - if ((d = this.dst) != null) { + if ((d = this.dst) != null && d.result == null) { try { u = fn.apply(arg); ex = null; @@ -477,7 +477,7 @@ public class CompletableFuture implem } public final boolean exec() { CompletableFuture d; V v; Throwable ex; - if ((d = this.dst) != null) { + if ((d = this.dst) != null && d.result == null) { try { v = fn.apply(arg1, arg2); ex = null; @@ -502,7 +502,7 @@ public class CompletableFuture implem } public final boolean exec() { CompletableFuture d; Throwable ex; - if ((d = this.dst) != null) { + if ((d = this.dst) != null && d.result == null) { try { fn.accept(arg); ex = null; @@ -528,7 +528,7 @@ public class CompletableFuture implem } public final boolean exec() { CompletableFuture d; Throwable ex; - if ((d = this.dst) != null) { + if ((d = this.dst) != null && d.result == null) { try { fn.accept(arg1, arg2); ex = null; @@ -2644,7 +2644,7 @@ public class CompletableFuture implem * completed. This method is designed for use only in error * recovery actions, and even in such situations may result in * ongoing dependent completions using established versus - * overwritten values. + * overwritten outcomes. * * @param value the completion value */ @@ -2653,6 +2653,22 @@ public class CompletableFuture implem postComplete(); } + /** + * Forcibly causes subsequent invocations of method get() and + * related methods to throw the given exception, whether or not + * already completed. This method is designed for use only in + * recovery actions, and even in such situations may result in + * ongoing dependent completions using established versus + * overwritten outcomes. + * + * @param ex the exception + */ + public void obtrudeException(Throwable ex) { + if (ex == null) throw new NullPointerException(); + result = new AltResult(ex); + postComplete(); + } + // Unsafe mechanics private static final sun.misc.Unsafe UNSAFE; private static final long RESULT;