ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CompletableFuture.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/CompletableFuture.java (file contents):
Revision 1.5 by dl, Fri Dec 28 14:03:11 2012 UTC vs.
Revision 1.6 by dl, Fri Dec 28 19:18:30 2012 UTC

# Line 5 | Line 5
5   */
6  
7   package java.util.concurrent;
8 import java.util.function.Block;
8   import java.util.function.Supplier;
9   import java.util.function.Function;
10   import java.util.function.BiFunction;
# Line 659 | Line 658 | public class CompletableFuture<T> implem
658      }
659  
660      /**
661 <     * Creates and returns a CompletableFuture that is completed after
662 <     * performing the given action with the exception triggering this
663 <     * CompletableFuture's completion if/when it completes
664 <     * exceptionally.
665 <     *
666 <     * @param action the action to perform before completing the
667 <     * returned CompletableFuture
661 >     * Creates and returns a CompletableFuture that is completed with
662 >     * the result of the given function of the exception triggering
663 >     * this CompletableFuture's completion if/when it completes
664 >     * exceptionally; Otherwise, if this CompletableFuture completes
665 >     * normally, then the returned CompletableFuture also completes
666 >     * normally with the same value.
667 >     *
668 >     * @param fn the function to use to compute the value of the
669 >     * returned CompletableFuture if this CompletableFuture completed
670 >     * exceptionally
671       * @return the new CompletableFuture
672       */
673 <    public CompletableFuture<Void> exceptionally(Block<Throwable> action) {
674 <        if (action == null) throw new NullPointerException();
675 <        CompletableFuture<Void> dst = new CompletableFuture<Void>();
673 >    public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn) {
674 >        if (fn == null) throw new NullPointerException();
675 >        CompletableFuture<T> dst = new CompletableFuture<T>();
676          ExceptionAction<T> d = null;
677 <        Object r; Throwable ex;
677 >        Object r;
678          if ((r = result) == null) {
679              CompletionNode p =
680 <                new CompletionNode(d = new ExceptionAction<T>(this, action, dst));
680 >                new CompletionNode(d = new ExceptionAction<T>(this, fn, dst));
681              while ((r = result) == null) {
682                  if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
683                                                  p.next = completions, p))
684                      break;
685              }
686          }
687 <        if (r != null && (d == null || d.compareAndSet(0, 1)) &&
688 <            (r instanceof AltResult) && (ex = ((AltResult)r).ex) != null)  {
689 <            try {
690 <                action.accept(ex);
691 <                dst.complete(null);
692 <            } catch (Throwable rex) {
693 <                dst.completeExceptionally(rex);
687 >        if (r != null && (d == null || d.compareAndSet(0, 1))) {
688 >            T t; Throwable ex = null;
689 >            if (r instanceof AltResult) {
690 >                if ((ex = ((AltResult)r).ex) != null)  {
691 >                    try {
692 >                        dst.complete(fn.apply(ex));
693 >                    } catch (Throwable rex) {
694 >                        dst.completeExceptionally(rex);
695 >                    }
696 >                }
697 >                t = null;
698              }
699 +            else
700 +                t = (T) r;
701 +            if (ex == null)
702 +                dst.complete(t);
703          }
704          if (r != null)
705              postComplete();
# Line 734 | Line 744 | public class CompletableFuture<T> implem
744      }
745  
746      /**
747 <     * Whether or not already completed, sets the value subsequently
748 <     * returned by method get() and related methods to the given
749 <     * value. This method is designed for use in error recovery
750 <     * actions, and is very unlikely to be useful otherwise.
747 >     * Forcibly sets or resets the value subsequently returned by
748 >     * method get() and related methods, whether or not already
749 >     * completed. This method is designed for use only in error
750 >     * recovery actions, and even in such situations may result in
751 >     * ongoing dependent completions using established versus
752 >     * overwritten values.
753       *
754       * @param value the completion value
755       */
756 <    public void force(T value) {
756 >    public void obtrudeValue(T value) {
757          result = (value == null) ? NIL : value;
758          postComplete();
759      }
# Line 1290 | Line 1302 | public class CompletableFuture<T> implem
1302  
1303      static final class ExceptionAction<T> extends Completion {
1304          final CompletableFuture<? extends T> src;
1305 <        final Block<? super Throwable> fn;
1306 <        final CompletableFuture<Void> dst;
1305 >        final Function<? super Throwable, ? extends T> fn;
1306 >        final CompletableFuture<T> dst;
1307          ExceptionAction(CompletableFuture<? extends T> src,
1308 <                        Block<? super Throwable> fn,
1309 <                        CompletableFuture<Void> dst) {
1308 >                        Function<? super Throwable, ? extends T> fn,
1309 >                        CompletableFuture<T> dst) {
1310              this.src = src; this.fn = fn; this.dst = dst;
1311          }
1312          public void run() {
1313              CompletableFuture<? extends T> a;
1314 <            Block<? super Throwable> fn;
1315 <            CompletableFuture<Void> dst;
1316 <            Object r; Throwable ex;
1314 >            Function<? super Throwable, ? extends T> fn;
1315 >            CompletableFuture<T> dst;
1316 >            Object r; T t; Throwable ex;
1317              if ((dst = this.dst) != null &&
1318                  (fn = this.fn) != null &&
1319                  (a = this.src) != null &&
1320                  (r = a.result) != null &&
1321                  compareAndSet(0, 1)) {
1322 <                if ((r instanceof AltResult) &&
1323 <                    (ex = ((AltResult)r).ex) != null)  {
1324 <                    try {
1325 <                        fn.accept(ex);
1326 <                        dst.complete(null);
1327 <                    } catch (Throwable rex) {
1328 <                        dst.completeExceptionally(rex);
1322 >                if (r instanceof AltResult) {
1323 >                    if ((ex = ((AltResult)r).ex) != null)  {
1324 >                        try {
1325 >                            dst.complete(fn.apply(ex));
1326 >                        } catch (Throwable rex) {
1327 >                            dst.completeExceptionally(rex);
1328 >                        }
1329 >                        return;
1330                      }
1331 +                    t = null;
1332                  }
1333 +                else
1334 +                    t = (T) r;
1335 +                dst.complete(t);
1336              }
1337          }
1338      }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines