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.191 by jsr166, Sun May 1 22:08:44 2016 UTC vs.
Revision 1.192 by dl, Thu Jun 2 13:16:27 2016 UTC

# Line 6 | Line 6
6  
7   package java.util.concurrent;
8  
9 + import java.lang.invoke.MethodHandles;
10 + import java.lang.invoke.VarHandle;
11   import java.util.concurrent.locks.LockSupport;
12   import java.util.function.BiConsumer;
13   import java.util.function.BiFunction;
# Line 223 | Line 225 | public class CompletableFuture<T> implem
225      volatile Completion stack;    // Top of Treiber stack of dependent actions
226  
227      final boolean internalComplete(Object r) { // CAS from null to r
228 <        return U.compareAndSwapObject(this, RESULT, null, r);
227 <    }
228 <
229 <    final boolean casStack(Completion cmp, Completion val) {
230 <        return U.compareAndSwapObject(this, STACK, cmp, val);
228 >        return RESULT.compareAndSet(this, (Object)null, r);
229      }
230  
231      /** Returns true if successfully pushed c onto stack. */
232      final boolean tryPushStack(Completion c) {
233          Completion h = stack;
234 <        lazySetNext(c, h);
235 <        return U.compareAndSwapObject(this, STACK, h, c);
234 >        NEXT.setRelease(c, h);
235 >        return STACK.compareAndSet(this, h, c);
236      }
237  
238      /** Unconditionally pushes c onto stack, retrying if necessary. */
# Line 254 | Line 252 | public class CompletableFuture<T> implem
252  
253      /** Completes with the null value, unless already completed. */
254      final boolean completeNull() {
255 <        return U.compareAndSwapObject(this, RESULT, null,
258 <                                      NIL);
255 >        return RESULT.compareAndSet(this, (Object)null, (Object)NIL);
256      }
257  
258      /** Returns the encoding of the given non-exceptional value. */
# Line 265 | Line 262 | public class CompletableFuture<T> implem
262  
263      /** Completes with a non-exceptional result, unless already completed. */
264      final boolean completeValue(T t) {
265 <        return U.compareAndSwapObject(this, RESULT, null,
269 <                                      (t == null) ? NIL : t);
265 >        return RESULT.compareAndSet(this, (Object)null, (t == null) ? NIL : t);
266      }
267  
268      /**
# Line 280 | Line 276 | public class CompletableFuture<T> implem
276  
277      /** Completes with an exceptional result, unless already completed. */
278      final boolean completeThrowable(Throwable x) {
279 <        return U.compareAndSwapObject(this, RESULT, null,
284 <                                      encodeThrowable(x));
279 >        return RESULT.compareAndSet(this, (Object)null, encodeThrowable(x));
280      }
281  
282      /**
# Line 308 | Line 303 | public class CompletableFuture<T> implem
303       * existing CompletionException.
304       */
305      final boolean completeThrowable(Throwable x, Object r) {
306 <        return U.compareAndSwapObject(this, RESULT, null,
312 <                                      encodeThrowable(x, r));
306 >        return RESULT.compareAndSet(this, (Object)null, encodeThrowable(x, r));
307      }
308  
309      /**
# Line 339 | Line 333 | public class CompletableFuture<T> implem
333       * If exceptional, r is first coerced to a CompletionException.
334       */
335      final boolean completeRelay(Object r) {
336 <        return U.compareAndSwapObject(this, RESULT, null,
343 <                                      encodeRelay(r));
336 >        return RESULT.compareAndSet(this, (Object)null, encodeRelay(r));
337      }
338  
339      /**
# Line 448 | Line 441 | public class CompletableFuture<T> implem
441          public final void setRawResult(Void v) {}
442      }
443  
451    static void lazySetNext(Completion c, Completion next) {
452        U.putObjectRelease(c, NEXT, next);
453    }
454
455    static boolean casNext(Completion c, Completion cmp, Completion val) {
456        return U.compareAndSwapObject(c, NEXT, cmp, val);
457    }
458
444      /**
445       * Pops and tries to trigger all reachable dependents.  Call only
446       * when known to be done.
# Line 470 | Line 455 | public class CompletableFuture<T> implem
455          while ((h = f.stack) != null ||
456                 (f != this && (h = (f = this).stack) != null)) {
457              CompletableFuture<?> d; Completion t;
458 <            if (f.casStack(h, t = h.next)) {
458 >            if (STACK.compareAndSet(f, h, t = h.next)) {
459                  if (t != null) {
460                      if (f != this) {
461                          pushStack(h);
462                          continue;
463                      }
464 <                    casNext(h, t, null);    // try to detach
464 >                    NEXT.compareAndSet(h, t, (Completion)null); // try to detach
465                  }
466                  f = (d = h.tryFire(NESTED)) == null ? this : d;
467              }
# Line 488 | Line 473 | public class CompletableFuture<T> implem
473          boolean unlinked = false;
474          Completion p;
475          while ((p = stack) != null && !p.isLive()) // ensure head of stack live
476 <            unlinked = casStack(p, p.next);
476 >            unlinked = STACK.compareAndSet(this, p, p.next);
477          if (p != null && !unlinked) {              // try to unlink first nonlive
478              for (Completion q = p.next; q != null;) {
479                  Completion s = q.next;
# Line 497 | Line 482 | public class CompletableFuture<T> implem
482                      q = s;
483                  }
484                  else {
485 <                    casNext(p, q, s);
485 >                    NEXT.compareAndSet(p, q, s);
486                      break;
487                  }
488              }
# Line 546 | Line 531 | public class CompletableFuture<T> implem
531          if (c != null) {
532              while (!tryPushStack(c)) {
533                  if (result != null) {
534 <                    lazySetNext(c, null);
534 >                    NEXT.setRelease(c, (Completion)null);
535                      break;
536                  }
537              }
# Line 1110 | Line 1095 | public class CompletableFuture<T> implem
1095          if (c != null) {
1096              Object r;
1097              while ((r = result) == null && !tryPushStack(c))
1098 <                lazySetNext(c, null); // clear on failure
1098 >                NEXT.setRelease(c, (Completion)null);  // clear on failure
1099              if (b != null && b != this && b.result == null) {
1100                  Completion q = (r != null) ? c : new CoCompletion(c);
1101                  while (b.result == null && !b.tryPushStack(q))
1102 <                    lazySetNext(q, null); // clear on failure
1102 >                    NEXT.setRelease(q, (Completion)null);  // clear on failure
1103              }
1104          }
1105      }
# Line 1429 | Line 1414 | public class CompletableFuture<T> implem
1414                          Completion q = new CoCompletion(c);
1415                          while (result == null && b.result == null &&
1416                                 !b.tryPushStack(q))
1417 <                            lazySetNext(q, null); // clear on failure
1417 >                            NEXT.setRelease(q, (Completion)null);  // clear on failure
1418                      }
1419                      break;
1420                  }
1421 <                lazySetNext(c, null); // clear on failure
1421 >                NEXT.setRelease(c, (Completion)null);  // clear on failure
1422              }
1423          }
1424      }
# Line 2856 | Line 2841 | public class CompletableFuture<T> implem
2841              throw new UnsupportedOperationException(); }
2842      }
2843  
2844 <    // Unsafe mechanics
2845 <    private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
2846 <    private static final long RESULT;
2847 <    private static final long STACK;
2863 <    private static final long NEXT;
2844 >    // VarHandle mechanics
2845 >    private static final VarHandle RESULT;
2846 >    private static final VarHandle STACK;
2847 >    private static final VarHandle NEXT;
2848      static {
2849          try {
2850 <            RESULT = U.objectFieldOffset
2851 <                (CompletableFuture.class.getDeclaredField("result"));
2852 <            STACK = U.objectFieldOffset
2853 <                (CompletableFuture.class.getDeclaredField("stack"));
2870 <            NEXT = U.objectFieldOffset
2871 <                (Completion.class.getDeclaredField("next"));
2850 >            MethodHandles.Lookup l = MethodHandles.lookup();
2851 >            RESULT = l.findVarHandle(CompletableFuture.class, "result", Object.class);
2852 >            STACK = l.findVarHandle(CompletableFuture.class, "stack", Completion.class);
2853 >            NEXT = l.findVarHandle(Completion.class, "next", Completion.class);
2854          } catch (ReflectiveOperationException e) {
2855              throw new Error(e);
2856          }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines