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.100 by jsr166, Mon Apr 7 15:51:32 2014 UTC vs.
Revision 1.101 by dl, Sun Apr 13 22:25:37 2014 UTC

# Line 103 | Line 103 | public class CompletableFuture<T> implem
103       * internal documentation for algorithmic details.
104       *
105       * 3. Completions are also kept in a list/stack, and pulled off
106 <     * and run when completion is triggered. (We could even use the
107 <     * same stack as for waiters, but would give up the potential
108 <     * parallelism obtained because woken waiters help release/run
109 <     * others -- see method postComplete).  Because post-processing
110 <     * may race with direct calls, class Completion opportunistically
111 <     * extends AtomicInteger so callers can claim the action via
112 <     * compareAndSet(0, 1).  The Completion.trigger methods are all
113 <     * written a boringly similar uniform way (that sometimes includes
114 <     * unnecessary-looking checks, kept to maintain uniformity).
115 <     * There are enough dimensions upon which they differ that
116 <     * attempts to factor commonalities while maintaining efficiency
117 <     * require more lines of code than they would save.
106 >     * and run when completion of an observable CF is triggered. (We
107 >     * could even use the same stack as for waiters, but would give up
108 >     * the potential parallelism obtained because woken waiters help
109 >     * release/run others -- see method postComplete).  Because
110 >     * post-processing may race with direct calls, class Completion
111 >     * opportunistically extends AtomicInteger so callers can claim
112 >     * the action via compareAndSet(0, 1).  The Completion.tryComplete
113 >     * methods are all written a boringly similar uniform way (that
114 >     * sometimes includes unnecessary-looking checks, kept to maintain
115 >     * uniformity).  There are enough dimensions upon which they
116 >     * differ that attempts to factor commonalities while maintaining
117 >     * efficiency require more lines of code than they would save.
118       *
119       * 4. The exported then/and/or methods do support a bit of
120       * factoring (see doThenApply etc). They must cope with the
# Line 150 | Line 150 | public class CompletableFuture<T> implem
150       * CompletionException unless it is one already.  Otherwise uses
151       * the given result, boxed as NIL if null.
152       */
153 <    final void setInternalResult(T v, Throwable ex) {
153 >    final void internalComplete(T v, Throwable ex) {
154          if (result == null)
155              UNSAFE.compareAndSwapObject
156                  (this, RESULT, null,
# Line 160 | Line 160 | public class CompletableFuture<T> implem
160      }
161  
162      /**
163 <     * Removes and signals all waiting threads.
164 <     */
165 <    final void removeAndSignalWaiters() {
166 <        WaitNode q; Thread t;
167 <        while ((q = waiters) != null) {
168 <            if (UNSAFE.compareAndSwapObject(this, WAITERS, q, q.next) &&
169 <                (t = q.thread) != null) {
170 <                q.thread = null;
171 <                LockSupport.unpark(t);
172 <            }
173 <        }
174 <    }
175 <
176 <    /**
177 <     * Triggers all enabled completions reachable from b.  Loopifies
178 <     * the final recursive call for each stage to avoid potential
179 <     * StackOverflowErrors in cases of long linear chains.
163 >     * Signals waiters and triggers all enabled dependent completions
164 >     * reachable from src.
165       *
166 <     * @param b if non-null, a completed CompletableFuture
166 >     * @param src if non-null a completed CompletableFuture
167       */
168 <    static final void removeAndTriggerCompletions(CompletableFuture<?> b) {
169 <        CompletionNode h; Completion c; CompletableFuture<?> f;
170 <        while (b != null && (h = b.completions) != null) {
171 <            if (UNSAFE.compareAndSwapObject(b, COMPLETIONS, h, h.next) &&
172 <                (c = h.completion) != null &&
173 <                (f = c.trigger()) != null &&
174 <                f.result != null) {
175 <                f.removeAndSignalWaiters();
176 <                if (f.completions != null) {
177 <                    if (b.completions == null)
178 <                        b = f; // tail-recurse
179 <                    else
180 <                        removeAndTriggerCompletions(f);
168 >    static final void postComplete(CompletableFuture<?> src) {
169 >        /*
170 >         * CF "src" is always the base of a possible chain of
171 >         * completions that may need further processing.  To avoid
172 >         * potential StackOverflowErrors, we extend along only one
173 >         * path ("dep") at a time, holding others by pushing them on
174 >         * src's completion list, which advances tail-recursion style
175 >         * when possible.  On each step, "f" is dep if non-null, else
176 >         * src.
177 >         */
178 >        for (CompletableFuture<?> f = src, dep = null; f != null;) {
179 >            WaitNode q; CompletionNode h; Thread w;
180 >            if ((q = f.waiters) != null) {
181 >                if (UNSAFE.compareAndSwapObject(f, WAITERS, q, q.next) &&
182 >                    (w = q.thread) != null) {
183 >                    q.thread = null;
184 >                    LockSupport.unpark(w);
185                  }
186              }
187 <        }
188 <    }
189 <
190 <    /**
191 <     * Sets result, signals waiters, and triggers dependents.
192 <     */
193 <    final void internalComplete(T v, Throwable ex) {
194 <        setInternalResult(v, ex);
195 <        removeAndSignalWaiters();
196 <        removeAndTriggerCompletions(this);
197 <    }
198 <
199 <
200 <    /**
201 <     * Signals waiters and triggers dependents. Call only if known to
202 <     * be completed.
203 <     */
204 <    final void postComplete() {
205 <        removeAndSignalWaiters();
206 <        removeAndTriggerCompletions(this);
207 <    }
208 <
209 <    /**
210 <     * If completed, helps signal waiters and trigger dependents.
211 <     */
212 <    final void helpPostComplete() {
224 <        if (result != null) {
225 <            removeAndSignalWaiters();
226 <            removeAndTriggerCompletions(this);
187 >            else if ((h = f.completions) == null) {
188 >                if (dep == null)
189 >                    break;
190 >                dep = null;
191 >                f = src;
192 >            }
193 >            else if (UNSAFE.compareAndSwapObject(f, COMPLETIONS, h, h.next)) {
194 >                Completion c; CompletableFuture<?> d;
195 >                if (dep != null && dep.completions != null) { // push to src
196 >                    do {} while (!UNSAFE.compareAndSwapObject(
197 >                                     src, COMPLETIONS,
198 >                                     h.next = src.completions, h));
199 >                }
200 >                else if ((c = h.completion) == null ||
201 >                         (d = c.tryComplete()) == null ||
202 >                         d.result == null) {
203 >                    dep = null;
204 >                    f = src;
205 >                }
206 >                else if (src.completions == null) {
207 >                    dep = null;
208 >                    f = src = d;
209 >                }
210 >                else
211 >                    f = dep = d;
212 >            }
213          }
214      }
215  
# Line 298 | Line 284 | public class CompletableFuture<T> implem
284                      q.thread = null;
285                      if (q.interruptControl < 0) {
286                          if (interruptible) {
287 <                            removeWaiter(q);
287 >                            removeCancelledWaiters();
288                              return null;
289                          }
290                          Thread.currentThread().interrupt();
291                      }
292                  }
293 <                postComplete(); // help release others
293 >                postComplete(this); // help release others
294                  return r;
295              }
296              else if (spins > 0) {
# Line 320 | Line 306 | public class CompletableFuture<T> implem
306                  queued = UNSAFE.compareAndSwapObject(this, WAITERS,
307                                                       q.next = waiters, q);
308              else if (interruptible && q.interruptControl < 0) {
309 <                removeWaiter(q);
309 >                q.thread = null;
310 >                removeCancelledWaiters();
311                  return null;
312              }
313              else if (q.thread != null && result == null) {
# Line 348 | Line 335 | public class CompletableFuture<T> implem
335                  if (q != null) {
336                      q.thread = null;
337                      if (q.interruptControl < 0) {
338 <                        removeWaiter(q);
338 >                        removeCancelledWaiters();
339                          throw new InterruptedException();
340                      }
341                  }
342 <                postComplete();
342 >                postComplete(this);
343                  return r;
344              }
345              else if (q == null) {
# Line 365 | Line 352 | public class CompletableFuture<T> implem
352                  queued = UNSAFE.compareAndSwapObject(this, WAITERS,
353                                                       q.next = waiters, q);
354              else if (q.interruptControl < 0) {
355 <                removeWaiter(q);
355 >                q.thread = null;
356 >                removeCancelledWaiters();
357                  throw new InterruptedException();
358              }
359              else if (q.nanos <= 0L) {
360                  if (result == null) {
361 <                    removeWaiter(q);
361 >                    q.thread = null;
362 >                    removeCancelledWaiters();
363                      throw new TimeoutException();
364                  }
365              }
# Line 385 | Line 374 | public class CompletableFuture<T> implem
374      }
375  
376      /**
377 <     * Tries to unlink a timed-out or interrupted wait node to avoid
377 >     * Tries to unlink timed-out or interrupted wait nodes to avoid
378       * accumulating garbage.  Internal nodes are simply unspliced
379       * without CAS since it is harmless if they are traversed anyway
380       * by releasers.  To avoid effects of unsplicing from already
# Line 394 | Line 383 | public class CompletableFuture<T> implem
383       * expect lists to be long enough to outweigh higher-overhead
384       * schemes.
385       */
386 <    private void removeWaiter(WaitNode node) {
387 <        if (node != null) {
388 <            node.thread = null;
389 <            retry:
390 <            for (;;) {          // restart on removeWaiter race
391 <                for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
392 <                    s = q.next;
393 <                    if (q.thread != null)
394 <                        pred = q;
406 <                    else if (pred != null) {
407 <                        pred.next = s;
408 <                        if (pred.thread == null) // check for race
409 <                            continue retry;
410 <                    }
411 <                    else if (!UNSAFE.compareAndSwapObject(this, WAITERS, q, s))
386 >    private void removeCancelledWaiters() {
387 >        retry: for (;;) {          // restart on removeWaiter race
388 >            for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
389 >                s = q.next;
390 >                if (q.thread != null)
391 >                    pred = q;
392 >                else if (pred != null) {
393 >                    pred.next = s;
394 >                    if (pred.thread == null) // check for race
395                          continue retry;
396                  }
397 <                break;
397 >                else if (!UNSAFE.compareAndSwapObject(this, WAITERS, q, s))
398 >                    continue retry;
399              }
400 +            break;
401          }
402      }
403  
# Line 467 | Line 452 | public class CompletableFuture<T> implem
452                  }
453                  d.internalComplete(null, ex);
454              }
455 +            postComplete(d);
456              return true;
457          }
458          private static final long serialVersionUID = 5232453952276885070L;
# Line 490 | Line 476 | public class CompletableFuture<T> implem
476                  }
477                  d.internalComplete(u, ex);
478              }
479 +            postComplete(d);
480              return true;
481          }
482          private static final long serialVersionUID = 5232453952276885070L;
# Line 515 | Line 502 | public class CompletableFuture<T> implem
502                  }
503                  d.internalComplete(u, ex);
504              }
505 +            postComplete(d);
506              return true;
507          }
508          private static final long serialVersionUID = 5232453952276885070L;
# Line 542 | Line 530 | public class CompletableFuture<T> implem
530                  }
531                  d.internalComplete(v, ex);
532              }
533 +            postComplete(d);
534              return true;
535          }
536          private static final long serialVersionUID = 5232453952276885070L;
# Line 566 | Line 555 | public class CompletableFuture<T> implem
555                  }
556                  d.internalComplete(null, ex);
557              }
558 +            postComplete(d);
559              return true;
560          }
561          private static final long serialVersionUID = 5232453952276885070L;
# Line 592 | Line 582 | public class CompletableFuture<T> implem
582                  }
583                  d.internalComplete(null, ex);
584              }
585 +            postComplete(d);
586              return true;
587          }
588          private static final long serialVersionUID = 5232453952276885070L;
# Line 634 | Line 625 | public class CompletableFuture<T> implem
625                  }
626                  d.internalComplete(u, ex);
627              }
628 +            postComplete(d);
629              return true;
630          }
631          private static final long serialVersionUID = 5232453952276885070L;
# Line 661 | Line 653 | public class CompletableFuture<T> implem
653                  }
654                  d.internalComplete(arg1, ex);
655              }
656 +            postComplete(d);
657              return true;
658          }
659          private static final long serialVersionUID = 5232453952276885070L;
# Line 684 | Line 677 | public class CompletableFuture<T> implem
677      @SuppressWarnings("serial")
678      abstract static class Completion extends AtomicInteger {
679          /**
680 <         * Complete a dependent Completablefuture if enabled
680 >         * Completes a dependent Completablefuture if enabled
681           * @return the dependent Completablefuture
682           */
683 <        public abstract CompletableFuture<?> trigger();
683 >        public abstract CompletableFuture<?> tryComplete();
684      }
685  
686      static final class ThenApply<T,U> extends Completion {
# Line 702 | Line 695 | public class CompletableFuture<T> implem
695              this.src = src; this.fn = fn; this.dst = dst;
696              this.executor = executor;
697          }
698 <        public final CompletableFuture<?> trigger() {
698 >        public final CompletableFuture<?> tryComplete() {
699              final CompletableFuture<? extends T> a;
700              final Function<? super T,? extends U> fn;
701              final CompletableFuture<U> dst;
# Line 711 | Line 704 | public class CompletableFuture<T> implem
704                  (fn = this.fn) != null &&
705                  (a = this.src) != null &&
706                  (r = a.result) != null &&
707 <                compareAndSet(0, 1)) {
707 >                get() == 0 && compareAndSet(0, 1)) {
708                  if (r instanceof AltResult) {
709                      ex = ((AltResult)r).ex;
710                      t = null;
# Line 734 | Line 727 | public class CompletableFuture<T> implem
727                      }
728                  }
729                  if (e == null || ex != null)
730 <                    dst.setInternalResult(u, ex);
730 >                    dst.internalComplete(u, ex);
731              }
732              return dst;
733          }
# Line 753 | Line 746 | public class CompletableFuture<T> implem
746              this.src = src; this.fn = fn; this.dst = dst;
747              this.executor = executor;
748          }
749 <        public final CompletableFuture<?> trigger() {
749 >        public final CompletableFuture<?> tryComplete() {
750              final CompletableFuture<? extends T> a;
751              final Consumer<? super T> fn;
752              final CompletableFuture<?> dst;
# Line 762 | Line 755 | public class CompletableFuture<T> implem
755                  (fn = this.fn) != null &&
756                  (a = this.src) != null &&
757                  (r = a.result) != null &&
758 <                compareAndSet(0, 1)) {
758 >                get() == 0 && compareAndSet(0, 1)) {
759                  if (r instanceof AltResult) {
760                      ex = ((AltResult)r).ex;
761                      t = null;
# Line 784 | Line 777 | public class CompletableFuture<T> implem
777                      }
778                  }
779                  if (e == null || ex != null)
780 <                    dst.setInternalResult(null, ex);
780 >                    dst.internalComplete(null, ex);
781              }
782              return dst;
783          }
# Line 803 | Line 796 | public class CompletableFuture<T> implem
796              this.src = src; this.fn = fn; this.dst = dst;
797              this.executor = executor;
798          }
799 <        public final CompletableFuture<?> trigger() {
799 >        public final CompletableFuture<?> tryComplete() {
800              final CompletableFuture<?> a;
801              final Runnable fn;
802              final CompletableFuture<Void> dst;
# Line 812 | Line 805 | public class CompletableFuture<T> implem
805                  (fn = this.fn) != null &&
806                  (a = this.src) != null &&
807                  (r = a.result) != null &&
808 <                compareAndSet(0, 1)) {
808 >                get() == 0 && compareAndSet(0, 1)) {
809                  if (r instanceof AltResult)
810                      ex = ((AltResult)r).ex;
811                  else
# Line 829 | Line 822 | public class CompletableFuture<T> implem
822                      }
823                  }
824                  if (e == null || ex != null)
825 <                    dst.setInternalResult(null, ex);
825 >                    dst.internalComplete(null, ex);
826              }
827              return dst;
828          }
# Line 851 | Line 844 | public class CompletableFuture<T> implem
844              this.fn = fn; this.dst = dst;
845              this.executor = executor;
846          }
847 <        public final CompletableFuture<?> trigger() {
847 >        public final CompletableFuture<?> tryComplete() {
848              final CompletableFuture<? extends T> a;
849              final CompletableFuture<? extends U> b;
850              final BiFunction<? super T,? super U,? extends V> fn;
# Line 863 | Line 856 | public class CompletableFuture<T> implem
856                  (r = a.result) != null &&
857                  (b = this.snd) != null &&
858                  (s = b.result) != null &&
859 <                compareAndSet(0, 1)) {
859 >                get() == 0 && compareAndSet(0, 1)) {
860                  if (r instanceof AltResult) {
861                      ex = ((AltResult)r).ex;
862                      t = null;
# Line 896 | Line 889 | public class CompletableFuture<T> implem
889                      }
890                  }
891                  if (e == null || ex != null)
892 <                    dst.setInternalResult(v, ex);
892 >                    dst.internalComplete(v, ex);
893              }
894              return dst;
895          }
# Line 918 | Line 911 | public class CompletableFuture<T> implem
911              this.fn = fn; this.dst = dst;
912              this.executor = executor;
913          }
914 <        public final CompletableFuture<?> trigger() {
914 >        public final CompletableFuture<?> tryComplete() {
915              final CompletableFuture<? extends T> a;
916              final CompletableFuture<? extends U> b;
917              final BiConsumer<? super T,? super U> fn;
# Line 930 | Line 923 | public class CompletableFuture<T> implem
923                  (r = a.result) != null &&
924                  (b = this.snd) != null &&
925                  (s = b.result) != null &&
926 <                compareAndSet(0, 1)) {
926 >                get() == 0 && compareAndSet(0, 1)) {
927                  if (r instanceof AltResult) {
928                      ex = ((AltResult)r).ex;
929                      t = null;
# Line 962 | Line 955 | public class CompletableFuture<T> implem
955                      }
956                  }
957                  if (e == null || ex != null)
958 <                    dst.setInternalResult(null, ex);
958 >                    dst.internalComplete(null, ex);
959              }
960              return dst;
961          }
# Line 984 | Line 977 | public class CompletableFuture<T> implem
977              this.fn = fn; this.dst = dst;
978              this.executor = executor;
979          }
980 <        public final CompletableFuture<?> trigger() {
980 >        public final CompletableFuture<?> tryComplete() {
981              final CompletableFuture<?> a;
982              final CompletableFuture<?> b;
983              final Runnable fn;
# Line 996 | Line 989 | public class CompletableFuture<T> implem
989                  (r = a.result) != null &&
990                  (b = this.snd) != null &&
991                  (s = b.result) != null &&
992 <                compareAndSet(0, 1)) {
992 >                get() == 0 && compareAndSet(0, 1)) {
993                  if (r instanceof AltResult)
994                      ex = ((AltResult)r).ex;
995                  else
# Line 1015 | Line 1008 | public class CompletableFuture<T> implem
1008                      }
1009                  }
1010                  if (e == null || ex != null)
1011 <                    dst.setInternalResult(null, ex);
1011 >                    dst.internalComplete(null, ex);
1012              }
1013              return dst;
1014          }
# Line 1031 | Line 1024 | public class CompletableFuture<T> implem
1024                        CompletableFuture<Void> dst) {
1025              this.src = src; this.snd = snd; this.dst = dst;
1026          }
1027 <        public final CompletableFuture<?> trigger() {
1027 >        public final CompletableFuture<?> tryComplete() {
1028              final CompletableFuture<?> a;
1029              final CompletableFuture<?> b;
1030              final CompletableFuture<Void> dst;
# Line 1041 | Line 1034 | public class CompletableFuture<T> implem
1034                  (r = a.result) != null &&
1035                  (b = this.snd) != null &&
1036                  (s = b.result) != null &&
1037 <                compareAndSet(0, 1)) {
1037 >                get() == 0 && compareAndSet(0, 1)) {
1038                  if (r instanceof AltResult)
1039                      ex = ((AltResult)r).ex;
1040                  else
1041                      ex = null;
1042                  if (ex == null && (s instanceof AltResult))
1043                      ex = ((AltResult)s).ex;
1044 <                dst.setInternalResult(null, ex);
1044 >                dst.internalComplete(null, ex);
1045              }
1046              return dst;
1047          }
# Line 1070 | Line 1063 | public class CompletableFuture<T> implem
1063              this.fn = fn; this.dst = dst;
1064              this.executor = executor;
1065          }
1066 <        public final CompletableFuture<?> trigger() {
1066 >        public final CompletableFuture<?> tryComplete() {
1067              final CompletableFuture<? extends T> a;
1068              final CompletableFuture<? extends T> b;
1069              final Function<? super T,? extends U> fn;
# Line 1080 | Line 1073 | public class CompletableFuture<T> implem
1073                  (fn = this.fn) != null &&
1074                  (((a = this.src) != null && (r = a.result) != null) ||
1075                   ((b = this.snd) != null && (r = b.result) != null)) &&
1076 <                compareAndSet(0, 1)) {
1076 >                get() == 0 && compareAndSet(0, 1)) {
1077                  if (r instanceof AltResult) {
1078                      ex = ((AltResult)r).ex;
1079                      t = null;
# Line 1103 | Line 1096 | public class CompletableFuture<T> implem
1096                      }
1097                  }
1098                  if (e == null || ex != null)
1099 <                    dst.setInternalResult(u, ex);
1099 >                    dst.internalComplete(u, ex);
1100              }
1101              return dst;
1102          }
# Line 1125 | Line 1118 | public class CompletableFuture<T> implem
1118              this.fn = fn; this.dst = dst;
1119              this.executor = executor;
1120          }
1121 <        public final CompletableFuture<?> trigger() {
1121 >        public final CompletableFuture<?> tryComplete() {
1122              final CompletableFuture<? extends T> a;
1123              final CompletableFuture<? extends T> b;
1124              final Consumer<? super T> fn;
# Line 1135 | Line 1128 | public class CompletableFuture<T> implem
1128                  (fn = this.fn) != null &&
1129                  (((a = this.src) != null && (r = a.result) != null) ||
1130                   ((b = this.snd) != null && (r = b.result) != null)) &&
1131 <                compareAndSet(0, 1)) {
1131 >                get() == 0 && compareAndSet(0, 1)) {
1132                  if (r instanceof AltResult) {
1133                      ex = ((AltResult)r).ex;
1134                      t = null;
# Line 1157 | Line 1150 | public class CompletableFuture<T> implem
1150                      }
1151                  }
1152                  if (e == null || ex != null)
1153 <                    dst.setInternalResult(null, ex);
1153 >                    dst.internalComplete(null, ex);
1154              }
1155              return dst;
1156          }
# Line 1179 | Line 1172 | public class CompletableFuture<T> implem
1172              this.fn = fn; this.dst = dst;
1173              this.executor = executor;
1174          }
1175 <        public final CompletableFuture<?> trigger() {
1175 >        public final CompletableFuture<?> tryComplete() {
1176              final CompletableFuture<?> a;
1177              final CompletableFuture<?> b;
1178              final Runnable fn;
# Line 1189 | Line 1182 | public class CompletableFuture<T> implem
1182                  (fn = this.fn) != null &&
1183                  (((a = this.src) != null && (r = a.result) != null) ||
1184                   ((b = this.snd) != null && (r = b.result) != null)) &&
1185 <                compareAndSet(0, 1)) {
1185 >                get() == 0 && compareAndSet(0, 1)) {
1186                  if (r instanceof AltResult)
1187                      ex = ((AltResult)r).ex;
1188                  else
# Line 1206 | Line 1199 | public class CompletableFuture<T> implem
1199                      }
1200                  }
1201                  if (e == null || ex != null)
1202 <                    dst.setInternalResult(null, ex);
1202 >                    dst.internalComplete(null, ex);
1203              }
1204              return dst;
1205          }
# Line 1222 | Line 1215 | public class CompletableFuture<T> implem
1215                       CompletableFuture<Object> dst) {
1216              this.src = src; this.snd = snd; this.dst = dst;
1217          }
1218 <        public final CompletableFuture<?> trigger() {
1218 >        public final CompletableFuture<?> tryComplete() {
1219              final CompletableFuture<?> a;
1220              final CompletableFuture<?> b;
1221              final CompletableFuture<Object> dst;
# Line 1230 | Line 1223 | public class CompletableFuture<T> implem
1223              if ((dst = this.dst) != null &&
1224                  (((a = this.src) != null && (r = a.result) != null) ||
1225                   ((b = this.snd) != null && (r = b.result) != null)) &&
1226 <                compareAndSet(0, 1)) {
1226 >                get() == 0 && compareAndSet(0, 1)) {
1227                  if (r instanceof AltResult) {
1228                      ex = ((AltResult)r).ex;
1229                      t = null;
# Line 1239 | Line 1232 | public class CompletableFuture<T> implem
1232                      ex = null;
1233                      t = r;
1234                  }
1235 <                dst.setInternalResult(t, ex);
1235 >                dst.internalComplete(t, ex);
1236              }
1237              return dst;
1238          }
# Line 1255 | Line 1248 | public class CompletableFuture<T> implem
1248                              CompletableFuture<T> dst) {
1249              this.src = src; this.fn = fn; this.dst = dst;
1250          }
1251 <        public final CompletableFuture<?> trigger() {
1251 >        public final CompletableFuture<?> tryComplete() {
1252              final CompletableFuture<? extends T> a;
1253              final Function<? super Throwable, ? extends T> fn;
1254              final CompletableFuture<T> dst;
# Line 1264 | Line 1257 | public class CompletableFuture<T> implem
1257                  (fn = this.fn) != null &&
1258                  (a = this.src) != null &&
1259                  (r = a.result) != null &&
1260 <                compareAndSet(0, 1)) {
1260 >                get() == 0 && compareAndSet(0, 1)) {
1261                  if ((r instanceof AltResult) &&
1262                      (ex = ((AltResult)r).ex) != null) {
1263                      try {
# Line 1277 | Line 1270 | public class CompletableFuture<T> implem
1270                      @SuppressWarnings("unchecked") T tr = (T) r;
1271                      t = tr;
1272                  }
1273 <                dst.setInternalResult(t, dx);
1273 >                dst.internalComplete(t, dx);
1274              }
1275              return dst;
1276          }
# Line 1290 | Line 1283 | public class CompletableFuture<T> implem
1283          final CompletableFuture<T> dst;
1284          final Executor executor;
1285          WhenCompleteCompletion(CompletableFuture<? extends T> src,
1286 <                                  BiConsumer<? super T, ? super Throwable> fn,
1287 <                                  CompletableFuture<T> dst,
1288 <                                  Executor executor) {
1286 >                               BiConsumer<? super T, ? super Throwable> fn,
1287 >                               CompletableFuture<T> dst,
1288 >                               Executor executor) {
1289              this.src = src; this.fn = fn; this.dst = dst;
1290              this.executor = executor;
1291          }
1292 <        public final CompletableFuture<?> trigger() {
1292 >        public final CompletableFuture<?> tryComplete() {
1293              final CompletableFuture<? extends T> a;
1294              final BiConsumer<? super T, ? super Throwable> fn;
1295              final CompletableFuture<T> dst;
# Line 1305 | Line 1298 | public class CompletableFuture<T> implem
1298                  (fn = this.fn) != null &&
1299                  (a = this.src) != null &&
1300                  (r = a.result) != null &&
1301 <                compareAndSet(0, 1)) {
1301 >                get() == 0 && compareAndSet(0, 1)) {
1302                  if (r instanceof AltResult) {
1303                      ex = ((AltResult)r).ex;
1304                      t = null;
# Line 1326 | Line 1319 | public class CompletableFuture<T> implem
1319                      dx = rex;
1320                  }
1321                  if (e == null || dx != null)
1322 <                    dst.setInternalResult(t, ex != null ? ex : dx);
1322 >                    dst.internalComplete(t, ex != null ? ex : dx);
1323              }
1324              return dst;
1325          }
# Line 1340 | Line 1333 | public class CompletableFuture<T> implem
1333                   CompletableFuture<T> dst) {
1334              this.src = src; this.dst = dst;
1335          }
1336 <        public final CompletableFuture<?> trigger() {
1336 >        public final CompletableFuture<?> tryComplete() {
1337              final CompletableFuture<?> a;
1338              final CompletableFuture<T> dst;
1339              Object r; T t; Throwable ex;
1340              if ((dst = this.dst) != null &&
1341                  (a = this.src) != null &&
1342                  (r = a.result) != null &&
1343 <                compareAndSet(0, 1)) {
1343 >                get() == 0 && compareAndSet(0, 1)) {
1344                  if (r instanceof AltResult) {
1345                      ex = ((AltResult)r).ex;
1346                      t = null;
# Line 1357 | Line 1350 | public class CompletableFuture<T> implem
1350                      @SuppressWarnings("unchecked") T tr = (T) r;
1351                      t = tr;
1352                  }
1353 <                dst.setInternalResult(t, ex);
1353 >                dst.internalComplete(t, ex);
1354              }
1355              return dst;
1356          }
# Line 1372 | Line 1365 | public class CompletableFuture<T> implem
1365                        CompletableFuture<Void> dst) {
1366              this.src = src; this.dst = dst;
1367          }
1368 <        public final CompletableFuture<?> trigger() {
1368 >        public final CompletableFuture<?> tryComplete() {
1369              final CompletableFuture<?> a;
1370              final CompletableFuture<Void> dst;
1371              Object r; Throwable ex;
1372              if ((dst = this.dst) != null &&
1373                  (a = this.src) != null &&
1374                  (r = a.result) != null &&
1375 <                compareAndSet(0, 1)) {
1375 >                get() == 0 && compareAndSet(0, 1)) {
1376                  if (r instanceof AltResult)
1377                      ex = ((AltResult)r).ex;
1378                  else
1379                      ex = null;
1380 <                dst.setInternalResult(null, ex);
1380 >                dst.internalComplete(null, ex);
1381              }
1382              return dst;
1383          }
# Line 1399 | Line 1392 | public class CompletableFuture<T> implem
1392          HandleCompletion(CompletableFuture<? extends T> src,
1393                           BiFunction<? super T, Throwable, ? extends U> fn,
1394                           CompletableFuture<U> dst,
1395 <                          Executor executor) {
1395 >                         Executor executor) {
1396              this.src = src; this.fn = fn; this.dst = dst;
1397              this.executor = executor;
1398          }
1399 <        public final CompletableFuture<?> trigger() {
1399 >        public final CompletableFuture<?> tryComplete() {
1400              final CompletableFuture<? extends T> a;
1401              final BiFunction<? super T, Throwable, ? extends U> fn;
1402              final CompletableFuture<U> dst;
# Line 1412 | Line 1405 | public class CompletableFuture<T> implem
1405                  (fn = this.fn) != null &&
1406                  (a = this.src) != null &&
1407                  (r = a.result) != null &&
1408 <                compareAndSet(0, 1)) {
1408 >                get() == 0 && compareAndSet(0, 1)) {
1409                  if (r instanceof AltResult) {
1410                      ex = ((AltResult)r).ex;
1411                      t = null;
# Line 1434 | Line 1427 | public class CompletableFuture<T> implem
1427                      dx = rex;
1428                  }
1429                  if (e == null || dx != null)
1430 <                    dst.setInternalResult(u, dx);
1430 >                    dst.internalComplete(u, dx);
1431              }
1432              return dst;
1433          }
# Line 1453 | Line 1446 | public class CompletableFuture<T> implem
1446              this.src = src; this.fn = fn; this.dst = dst;
1447              this.executor = executor;
1448          }
1449 <        public final CompletableFuture<?> trigger() {
1449 >        public final CompletableFuture<?> tryComplete() {
1450              final CompletableFuture<? extends T> a;
1451              final Function<? super T, ? extends CompletionStage<U>> fn;
1452              final CompletableFuture<U> dst;
# Line 1462 | Line 1455 | public class CompletableFuture<T> implem
1455                  (fn = this.fn) != null &&
1456                  (a = this.src) != null &&
1457                  (r = a.result) != null &&
1458 <                compareAndSet(0, 1)) {
1458 >                get() == 0 && compareAndSet(0, 1)) {
1459                  if (r instanceof AltResult) {
1460                      ex = ((AltResult)r).ex;
1461                      t = null;
# Line 1490 | Line 1483 | public class CompletableFuture<T> implem
1483                      }
1484                  }
1485                  if (c != null) {
1493                    ThenCopy<U> d = null;
1486                      Object s;
1487                      if ((s = c.result) == null) {
1488 <                        CompletionNode p = new CompletionNode
1489 <                            (d = new ThenCopy<U>(c, dst));
1488 >                        ThenCopy<U> d = new ThenCopy<U>(c, dst);
1489 >                        CompletionNode p = new CompletionNode(d);
1490                          while ((s = c.result) == null) {
1491                              if (UNSAFE.compareAndSwapObject
1492                                  (c, COMPLETIONS, p.next = c.completions, p))
1493                                  break;
1494                          }
1495 +                        d.tryComplete();
1496                      }
1497 <                    if (s != null && (d == null || d.compareAndSet(0, 1))) {
1497 >                    else {
1498                          complete = true;
1499                          if (s instanceof AltResult) {
1500                              ex = ((AltResult)s).ex;  // no rewrap
# Line 1514 | Line 1507 | public class CompletableFuture<T> implem
1507                      }
1508                  }
1509                  if (complete || ex != null)
1510 <                    dst.setInternalResult(u, ex);
1518 <                if (c != null)
1519 <                    c.helpPostComplete();
1510 >                    dst.internalComplete(u, ex);
1511              }
1512              return dst;
1513          }
# Line 1530 | Line 1521 | public class CompletableFuture<T> implem
1521           Executor e) {
1522          if (fn == null) throw new NullPointerException();
1523          CompletableFuture<U> dst = new CompletableFuture<U>();
1533        ThenApply<T,U> d = null;
1524          Object r;
1525          if ((r = result) == null) {
1526 <            CompletionNode p = new CompletionNode
1527 <                (d = new ThenApply<T,U>(this, fn, dst, e));
1528 <            while ((r = result) == null) {
1526 >            ThenApply<T,U> d = new ThenApply<T,U>(this, fn, dst, e);
1527 >            CompletionNode p = new CompletionNode(d);
1528 >            while (result == null) {
1529                  if (UNSAFE.compareAndSwapObject
1530                      (this, COMPLETIONS, p.next = completions, p))
1531                      break;
1532              }
1533 +            d.tryComplete();
1534          }
1535 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
1535 >        else {
1536              T t; Throwable ex;
1537              if (r instanceof AltResult) {
1538                  ex = ((AltResult)r).ex;
# Line 1566 | Line 1557 | public class CompletableFuture<T> implem
1557              if (e == null || ex != null)
1558                  dst.internalComplete(u, ex);
1559          }
1569        helpPostComplete();
1560          return dst;
1561      }
1562  
# Line 1574 | Line 1564 | public class CompletableFuture<T> implem
1564                                                   Executor e) {
1565          if (fn == null) throw new NullPointerException();
1566          CompletableFuture<Void> dst = new CompletableFuture<Void>();
1577        ThenAccept<T> d = null;
1567          Object r;
1568          if ((r = result) == null) {
1569 <            CompletionNode p = new CompletionNode
1570 <                (d = new ThenAccept<T>(this, fn, dst, e));
1571 <            while ((r = result) == null) {
1569 >            ThenAccept<T> d = new ThenAccept<T>(this, fn, dst, e);
1570 >            CompletionNode p = new CompletionNode(d);
1571 >            while (result == null) {
1572                  if (UNSAFE.compareAndSwapObject
1573                      (this, COMPLETIONS, p.next = completions, p))
1574                      break;
1575              }
1576 +            d.tryComplete();
1577          }
1578 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
1578 >        else {
1579              T t; Throwable ex;
1580              if (r instanceof AltResult) {
1581                  ex = ((AltResult)r).ex;
# Line 1609 | Line 1599 | public class CompletableFuture<T> implem
1599              if (e == null || ex != null)
1600                  dst.internalComplete(null, ex);
1601          }
1612        helpPostComplete();
1602          return dst;
1603      }
1604  
# Line 1617 | Line 1606 | public class CompletableFuture<T> implem
1606                                                Executor e) {
1607          if (action == null) throw new NullPointerException();
1608          CompletableFuture<Void> dst = new CompletableFuture<Void>();
1620        ThenRun d = null;
1609          Object r;
1610          if ((r = result) == null) {
1611 <            CompletionNode p = new CompletionNode
1612 <                (d = new ThenRun(this, action, dst, e));
1613 <            while ((r = result) == null) {
1611 >            ThenRun d = new ThenRun(this, action, dst, e);
1612 >            CompletionNode p = new CompletionNode(d);
1613 >            while (result == null) {
1614                  if (UNSAFE.compareAndSwapObject
1615                      (this, COMPLETIONS, p.next = completions, p))
1616                      break;
1617              }
1618 +            d.tryComplete();
1619          }
1620 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
1620 >        else {
1621              Throwable ex;
1622              if (r instanceof AltResult)
1623                  ex = ((AltResult)r).ex;
# Line 1647 | Line 1636 | public class CompletableFuture<T> implem
1636              if (e == null || ex != null)
1637                  dst.internalComplete(null, ex);
1638          }
1650        helpPostComplete();
1639          return dst;
1640      }
1641  
# Line 1657 | Line 1645 | public class CompletableFuture<T> implem
1645           Executor e) {
1646          if (other == null || fn == null) throw new NullPointerException();
1647          CompletableFuture<V> dst = new CompletableFuture<V>();
1648 <        ThenCombine<T,U,V> d = null;
1649 <        Object r, s = null;
1650 <        if ((r = result) == null || (s = other.result) == null) {
1651 <            d = new ThenCombine<T,U,V>(this, other, fn, dst, e);
1648 >        Object r = result, s = other.result;
1649 >        if (r == null || s == null) {
1650 >            ThenCombine<T,U,V> d =
1651 >                new ThenCombine<T,U,V>(this, other, fn, dst, e);
1652              CompletionNode q = null, p = new CompletionNode(d);
1653              while ((r == null && (r = result) == null) ||
1654                     (s == null && (s = other.result) == null)) {
# Line 1678 | Line 1666 | public class CompletableFuture<T> implem
1666                      q = new CompletionNode(d);
1667                  }
1668              }
1669 +            d.tryComplete();
1670          }
1671 <        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
1671 >        else {
1672              T t; U u; Throwable ex;
1673              if (r instanceof AltResult) {
1674                  ex = ((AltResult)r).ex;
# Line 1714 | Line 1703 | public class CompletableFuture<T> implem
1703              if (e == null || ex != null)
1704                  dst.internalComplete(v, ex);
1705          }
1717        helpPostComplete();
1718        other.helpPostComplete();
1706          return dst;
1707      }
1708  
# Line 1725 | Line 1712 | public class CompletableFuture<T> implem
1712           Executor e) {
1713          if (other == null || fn == null) throw new NullPointerException();
1714          CompletableFuture<Void> dst = new CompletableFuture<Void>();
1715 <        ThenAcceptBoth<T,U> d = null;
1716 <        Object r, s = null;
1717 <        if ((r = result) == null || (s = other.result) == null) {
1718 <            d = new ThenAcceptBoth<T,U>(this, other, fn, dst, e);
1715 >        Object r = result, s = other.result;
1716 >        if (r == null || s == null) {
1717 >            ThenAcceptBoth<T,U> d =
1718 >                new ThenAcceptBoth<T,U>(this, other, fn, dst, e);
1719              CompletionNode q = null, p = new CompletionNode(d);
1720              while ((r == null && (r = result) == null) ||
1721                     (s == null && (s = other.result) == null)) {
# Line 1746 | Line 1733 | public class CompletableFuture<T> implem
1733                      q = new CompletionNode(d);
1734                  }
1735              }
1736 +            d.tryComplete();
1737          }
1738 <        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
1738 >        else {
1739              T t; U u; Throwable ex;
1740              if (r instanceof AltResult) {
1741                  ex = ((AltResult)r).ex;
# Line 1781 | Line 1769 | public class CompletableFuture<T> implem
1769              if (e == null || ex != null)
1770                  dst.internalComplete(null, ex);
1771          }
1784        helpPostComplete();
1785        other.helpPostComplete();
1772          return dst;
1773      }
1774  
# Line 1791 | Line 1777 | public class CompletableFuture<T> implem
1777                                                     Executor e) {
1778          if (other == null || action == null) throw new NullPointerException();
1779          CompletableFuture<Void> dst = new CompletableFuture<Void>();
1780 <        RunAfterBoth d = null;
1781 <        Object r, s = null;
1782 <        if ((r = result) == null || (s = other.result) == null) {
1797 <            d = new RunAfterBoth(this, other, action, dst, e);
1780 >        Object r = result, s = other.result;
1781 >        if (r == null || s == null) {
1782 >            RunAfterBoth d = new RunAfterBoth(this, other, action, dst, e);
1783              CompletionNode q = null, p = new CompletionNode(d);
1784              while ((r == null && (r = result) == null) ||
1785                     (s == null && (s = other.result) == null)) {
# Line 1812 | Line 1797 | public class CompletableFuture<T> implem
1797                      q = new CompletionNode(d);
1798                  }
1799              }
1800 +            d.tryComplete();
1801          }
1802 <        if (r != null && s != null && (d == null || d.compareAndSet(0, 1))) {
1802 >        else {
1803              Throwable ex;
1804              if (r instanceof AltResult)
1805                  ex = ((AltResult)r).ex;
# Line 1834 | Line 1820 | public class CompletableFuture<T> implem
1820              if (e == null || ex != null)
1821                  dst.internalComplete(null, ex);
1822          }
1837        helpPostComplete();
1838        other.helpPostComplete();
1823          return dst;
1824      }
1825  
# Line 1845 | Line 1829 | public class CompletableFuture<T> implem
1829           Executor e) {
1830          if (other == null || fn == null) throw new NullPointerException();
1831          CompletableFuture<U> dst = new CompletableFuture<U>();
1848        ApplyToEither<T,U> d = null;
1832          Object r;
1833          if ((r = result) == null && (r = other.result) == null) {
1834 <            d = new ApplyToEither<T,U>(this, other, fn, dst, e);
1834 >            ApplyToEither<T,U> d =
1835 >                new ApplyToEither<T,U>(this, other, fn, dst, e);
1836              CompletionNode q = null, p = new CompletionNode(d);
1837 <            while ((r = result) == null && (r = other.result) == null) {
1837 >            while (result == null && other.result == null) {
1838                  if (q != null) {
1839                      if (UNSAFE.compareAndSwapObject
1840                          (other, COMPLETIONS, q.next = other.completions, q))
# Line 1860 | Line 1844 | public class CompletableFuture<T> implem
1844                           (this, COMPLETIONS, p.next = completions, p))
1845                      q = new CompletionNode(d);
1846              }
1847 +            d.tryComplete();
1848          }
1849 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
1849 >        else {
1850              T t; Throwable ex;
1851              if (r instanceof AltResult) {
1852                  ex = ((AltResult)r).ex;
# Line 1886 | Line 1871 | public class CompletableFuture<T> implem
1871              if (e == null || ex != null)
1872                  dst.internalComplete(u, ex);
1873          }
1889        helpPostComplete();
1890        other.helpPostComplete();
1874          return dst;
1875      }
1876  
# Line 1897 | Line 1880 | public class CompletableFuture<T> implem
1880           Executor e) {
1881          if (other == null || fn == null) throw new NullPointerException();
1882          CompletableFuture<Void> dst = new CompletableFuture<Void>();
1900        AcceptEither<T> d = null;
1883          Object r;
1884          if ((r = result) == null && (r = other.result) == null) {
1885 <            d = new AcceptEither<T>(this, other, fn, dst, e);
1885 >            AcceptEither<T> d =
1886 >                new AcceptEither<T>(this, other, fn, dst, e);
1887              CompletionNode q = null, p = new CompletionNode(d);
1888 <            while ((r = result) == null && (r = other.result) == null) {
1888 >            while (result == null && other.result == null) {
1889                  if (q != null) {
1890                      if (UNSAFE.compareAndSwapObject
1891                          (other, COMPLETIONS, q.next = other.completions, q))
# Line 1912 | Line 1895 | public class CompletableFuture<T> implem
1895                           (this, COMPLETIONS, p.next = completions, p))
1896                      q = new CompletionNode(d);
1897              }
1898 +            d.tryComplete();
1899          }
1900 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
1900 >        else {
1901              T t; Throwable ex;
1902              if (r instanceof AltResult) {
1903                  ex = ((AltResult)r).ex;
# Line 1937 | Line 1921 | public class CompletableFuture<T> implem
1921              if (e == null || ex != null)
1922                  dst.internalComplete(null, ex);
1923          }
1940        helpPostComplete();
1941        other.helpPostComplete();
1924          return dst;
1925      }
1926  
# Line 1948 | Line 1930 | public class CompletableFuture<T> implem
1930           Executor e) {
1931          if (other == null || action == null) throw new NullPointerException();
1932          CompletableFuture<Void> dst = new CompletableFuture<Void>();
1951        RunAfterEither d = null;
1933          Object r;
1934          if ((r = result) == null && (r = other.result) == null) {
1935 <            d = new RunAfterEither(this, other, action, dst, e);
1935 >            RunAfterEither d =
1936 >                new RunAfterEither(this, other, action, dst, e);
1937              CompletionNode q = null, p = new CompletionNode(d);
1938 <            while ((r = result) == null && (r = other.result) == null) {
1938 >            while (result == null && other.result == null) {
1939                  if (q != null) {
1940                      if (UNSAFE.compareAndSwapObject
1941                          (other, COMPLETIONS, q.next = other.completions, q))
# Line 1963 | Line 1945 | public class CompletableFuture<T> implem
1945                           (this, COMPLETIONS, p.next = completions, p))
1946                      q = new CompletionNode(d);
1947              }
1948 +            d.tryComplete();
1949          }
1950 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
1950 >        else {
1951              Throwable ex;
1952              if (r instanceof AltResult)
1953                  ex = ((AltResult)r).ex;
# Line 1983 | Line 1966 | public class CompletableFuture<T> implem
1966              if (e == null || ex != null)
1967                  dst.internalComplete(null, ex);
1968          }
1986        helpPostComplete();
1987        other.helpPostComplete();
1969          return dst;
1970      }
1971  
# Line 1993 | Line 1974 | public class CompletableFuture<T> implem
1974           Executor e) {
1975          if (fn == null) throw new NullPointerException();
1976          CompletableFuture<U> dst = null;
1996        ThenCompose<T,U> d = null;
1977          Object r;
1978          if ((r = result) == null) {
1979              dst = new CompletableFuture<U>();
1980 <            CompletionNode p = new CompletionNode
1981 <                (d = new ThenCompose<T,U>(this, fn, dst, e));
1982 <            while ((r = result) == null) {
1980 >            ThenCompose<T,U> d = new ThenCompose<T,U>(this, fn, dst, e);
1981 >            CompletionNode p = new CompletionNode(d);
1982 >            while (result == null) {
1983                  if (UNSAFE.compareAndSwapObject
1984                      (this, COMPLETIONS, p.next = completions, p))
1985                      break;
1986              }
1987 +            d.tryComplete();
1988          }
1989 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
1989 >        else {
1990              T t; Throwable ex;
1991              if (r instanceof AltResult) {
1992                  ex = ((AltResult)r).ex;
# Line 2038 | Line 2019 | public class CompletableFuture<T> implem
2019              if (ex != null)
2020                  dst.internalComplete(null, ex);
2021          }
2041        helpPostComplete();
2042        dst.helpPostComplete();
2022          return dst;
2023      }
2024  
# Line 2048 | Line 2027 | public class CompletableFuture<T> implem
2027           Executor e) {
2028          if (fn == null) throw new NullPointerException();
2029          CompletableFuture<T> dst = new CompletableFuture<T>();
2051        WhenCompleteCompletion<T> d = null;
2030          Object r;
2031          if ((r = result) == null) {
2032 <            CompletionNode p =
2033 <                new CompletionNode(d = new WhenCompleteCompletion<T>
2034 <                                   (this, fn, dst, e));
2035 <            while ((r = result) == null) {
2032 >            WhenCompleteCompletion<T> d =
2033 >                new WhenCompleteCompletion<T>(this, fn, dst, e);
2034 >            CompletionNode p = new CompletionNode(d);
2035 >            while (result == null) {
2036                  if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
2037                                                  p.next = completions, p))
2038                      break;
2039              }
2040 +            d.tryComplete();
2041          }
2042 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
2042 >        else {
2043              T t; Throwable ex;
2044              if (r instanceof AltResult) {
2045                  ex = ((AltResult)r).ex;
# Line 2083 | Line 2062 | public class CompletableFuture<T> implem
2062              if (e == null || dx != null)
2063                  dst.internalComplete(t, ex != null ? ex : dx);
2064          }
2086        helpPostComplete();
2065          return dst;
2066      }
2067  
# Line 2092 | Line 2070 | public class CompletableFuture<T> implem
2070           Executor e) {
2071          if (fn == null) throw new NullPointerException();
2072          CompletableFuture<U> dst = new CompletableFuture<U>();
2095        HandleCompletion<T,U> d = null;
2073          Object r;
2074          if ((r = result) == null) {
2075 <            CompletionNode p =
2076 <                new CompletionNode(d = new HandleCompletion<T,U>
2077 <                                   (this, fn, dst, e));
2078 <            while ((r = result) == null) {
2075 >            HandleCompletion<T,U> d =
2076 >                new HandleCompletion<T,U>(this, fn, dst, e);
2077 >            CompletionNode p = new CompletionNode(d);
2078 >            while (result == null) {
2079                  if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
2080                                                  p.next = completions, p))
2081                      break;
2082              }
2083 +            d.tryComplete();
2084          }
2085 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
2085 >        else {
2086              T t; Throwable ex;
2087              if (r instanceof AltResult) {
2088                  ex = ((AltResult)r).ex;
# Line 2131 | Line 2109 | public class CompletableFuture<T> implem
2109              if (e == null || dx != null)
2110                  dst.internalComplete(u, dx);
2111          }
2134        helpPostComplete();
2112          return dst;
2113      }
2114  
2138
2115      // public methods
2116  
2117      /**
# Line 2373 | Line 2349 | public class CompletableFuture<T> implem
2349          boolean triggered = result == null &&
2350              UNSAFE.compareAndSwapObject(this, RESULT, null,
2351                                          value == null ? NIL : value);
2352 <        postComplete();
2352 >        postComplete(this);
2353          return triggered;
2354      }
2355  
# Line 2389 | Line 2365 | public class CompletableFuture<T> implem
2365          if (ex == null) throw new NullPointerException();
2366          boolean triggered = result == null &&
2367              UNSAFE.compareAndSwapObject(this, RESULT, null, new AltResult(ex));
2368 <        postComplete();
2368 >        postComplete(this);
2369          return triggered;
2370      }
2371  
# Line 2653 | Line 2629 | public class CompletableFuture<T> implem
2629          (Function<Throwable, ? extends T> fn) {
2630          if (fn == null) throw new NullPointerException();
2631          CompletableFuture<T> dst = new CompletableFuture<T>();
2656        ExceptionCompletion<T> d = null;
2632          Object r;
2633          if ((r = result) == null) {
2634 <            CompletionNode p =
2635 <                new CompletionNode(d = new ExceptionCompletion<T>
2636 <                                   (this, fn, dst));
2637 <            while ((r = result) == null) {
2634 >            ExceptionCompletion<T> d =
2635 >                new ExceptionCompletion<T>(this, fn, dst);
2636 >            CompletionNode p = new CompletionNode(d);
2637 >            while (result == null) {
2638                  if (UNSAFE.compareAndSwapObject(this, COMPLETIONS,
2639                                                  p.next = completions, p))
2640                      break;
2641              }
2642 +            d.tryComplete();
2643          }
2644 <        if (r != null && (d == null || d.compareAndSet(0, 1))) {
2644 >        else {
2645              T t = null; Throwable ex, dx = null;
2646              if (r instanceof AltResult) {
2647                  if ((ex = ((AltResult)r).ex) != null) {
# Line 2682 | Line 2658 | public class CompletableFuture<T> implem
2658              }
2659              dst.internalComplete(t, dx);
2660          }
2685        helpPostComplete();
2661          return dst;
2662      }
2663  
# Line 2742 | Line 2717 | public class CompletableFuture<T> implem
2717                               (f, COMPLETIONS, p.next = f.completions, p))
2718                          break;
2719                  }
2720 <                if (r != null && (d == null || d.compareAndSet(0, 1)))
2720 >                if (d != null)
2721 >                    d.tryComplete();
2722 >                else
2723                      dst.internalComplete(null, (r instanceof AltResult) ?
2724                                           ((AltResult)r).ex : null);
2748                f.helpPostComplete();
2725              }
2726              return dst;
2727          }
# Line 2780 | Line 2756 | public class CompletableFuture<T> implem
2756                       (snd, COMPLETIONS, q.next = snd.completions, q))
2757                  break;
2758          }
2759 <        if ((r != null || (r = fst.result) != null) &&
2760 <            (s != null || (s = snd.result) != null) &&
2761 <            (d == null || d.compareAndSet(0, 1))) {
2759 >        if (d != null)
2760 >            d.tryComplete();
2761 >        else {
2762              Throwable ex;
2763              if (r instanceof AltResult)
2764                  ex = ((AltResult)r).ex;
# Line 2792 | Line 2768 | public class CompletableFuture<T> implem
2768                  ex = ((AltResult)s).ex;
2769              dst.internalComplete(null, ex);
2770          }
2795        fst.helpPostComplete();
2796        snd.helpPostComplete();
2771          return dst;
2772      }
2773  
# Line 2836 | Line 2810 | public class CompletableFuture<T> implem
2810                               (f, COMPLETIONS, p.next = f.completions, p))
2811                          break;
2812                  }
2813 <                if (r != null && (d == null || d.compareAndSet(0, 1))) {
2813 >                if (d != null)
2814 >                    d.tryComplete();
2815 >                else {
2816                      Throwable ex; Object t;
2817                      if (r instanceof AltResult) {
2818                          ex = ((AltResult)r).ex;
# Line 2848 | Line 2824 | public class CompletableFuture<T> implem
2824                      }
2825                      dst.internalComplete(t, ex);
2826                  }
2851                f.helpPostComplete();
2827              }
2828              return dst;
2829          }
# Line 2882 | Line 2857 | public class CompletableFuture<T> implem
2857                       (snd, COMPLETIONS, q.next = snd.completions, q))
2858                  break;
2859          }
2860 <        if ((r != null || (r = fst.result) != null ||
2861 <             (r = snd.result) != null) &&
2862 <            (d == null || d.compareAndSet(0, 1))) {
2860 >        if (d != null)
2861 >            d.tryComplete();
2862 >        else {
2863              Throwable ex; Object t;
2864              if (r instanceof AltResult) {
2865                  ex = ((AltResult)r).ex;
# Line 2896 | Line 2871 | public class CompletableFuture<T> implem
2871              }
2872              dst.internalComplete(t, ex);
2873          }
2899        fst.helpPostComplete();
2900        snd.helpPostComplete();
2874          return dst;
2875      }
2876  
# Line 2920 | Line 2893 | public class CompletableFuture<T> implem
2893          boolean cancelled = (result == null) &&
2894              UNSAFE.compareAndSwapObject
2895              (this, RESULT, null, new AltResult(new CancellationException()));
2896 <        postComplete();
2896 >        postComplete(this);
2897          return cancelled || isCancelled();
2898      }
2899  
# Line 2964 | Line 2937 | public class CompletableFuture<T> implem
2937       */
2938      public void obtrudeValue(T value) {
2939          result = (value == null) ? NIL : value;
2940 <        postComplete();
2940 >        postComplete(this);
2941      }
2942  
2943      /**
# Line 2980 | Line 2953 | public class CompletableFuture<T> implem
2953      public void obtrudeException(Throwable ex) {
2954          if (ex == null) throw new NullPointerException();
2955          result = new AltResult(ex);
2956 <        postComplete();
2956 >        postComplete(this);
2957      }
2958  
2959      /**

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines