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.128 by jsr166, Mon Jun 16 20:38:11 2014 UTC vs.
Revision 1.129 by jsr166, Wed Jun 18 04:12:17 2014 UTC

# Line 196 | Line 196 | public class CompletableFuture<T> implem
196          return UNSAFE.compareAndSwapObject(this, STACK, cmp, val);
197      }
198  
199 +    /** Returns true if successfully pushed c onto stack. */
200 +    final boolean tryPushStack(Completion c) {
201 +        Completion h = stack;
202 +        c.lazySetNext(h);
203 +        return UNSAFE.compareAndSwapObject(this, STACK, h, c);
204 +    }
205 +
206 +    /** Unconditionally pushes c onto stack, retrying if necessary. */
207 +    final void pushStack(Completion c) {
208 +        do {} while (!tryPushStack(c));
209 +    }
210 +
211      /* ------------- Encoding and decoding outcomes -------------- */
212  
213      static final class AltResult { // See above
# Line 401 | Line 413 | public class CompletableFuture<T> implem
413          public final boolean exec()            { tryFire(ASYNC); return true; }
414          public final Void getRawResult()       { return null; }
415          public final void setRawResult(Void v) {}
416 +
417 +        void lazySetNext(Completion val) {
418 +            UNSAFE.putOrderedObject(this, NEXT, val);
419 +        }
420 +
421 +        // Unsafe mechanics
422 +
423 +        private static final sun.misc.Unsafe UNSAFE;
424 +        private static final long NEXT;
425 +
426 +        static {
427 +            try {
428 +                UNSAFE = sun.misc.Unsafe.getUnsafe();
429 +                NEXT = UNSAFE.objectFieldOffset
430 +                    (Completion.class.getDeclaredField("next"));
431 +            } catch (Exception e) {
432 +                throw new Error(e);
433 +            }
434 +        }
435      }
436  
437      /**
# Line 419 | Line 450 | public class CompletableFuture<T> implem
450              CompletableFuture<?> d; Completion t;
451              if (f.casStack(h, t = h.next)) {
452                  if (t != null) {
453 <                    if (f != this) {  // push
454 <                        do {} while (!casStack(h.next = stack, h));
453 >                    if (f != this) {
454 >                        pushStack(h);
455                          continue;
456                      }
457                      h.next = null;    // detach
# Line 491 | Line 522 | public class CompletableFuture<T> implem
522      /** Pushes the given completion (if it exists) unless done. */
523      final void push(UniCompletion<?,?> c) {
524          if (c != null) {
525 <            while (result == null && !casStack(c.next = stack, c))
526 <                c.next = null; // clear on failure
525 >            while (result == null && !tryPushStack(c))
526 >                c.lazySetNext(null); // clear on failure
527          }
528      }
529  
# Line 978 | Line 1009 | public class CompletableFuture<T> implem
1009      final void bipush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
1010          if (c != null) {
1011              Object r;
1012 <            while ((r = result) == null && !casStack(c.next = stack, c))
1013 <                c.next = null;
1012 >            while ((r = result) == null && !tryPushStack(c))
1013 >                c.lazySetNext(null); // clear on failure
1014              if (b != null && b != this && b.result == null) {
1015                  Completion q = (r != null) ? c : new CoCompletion(c);
1016 <                while (b.result == null && !b.casStack(q.next = b.stack, q))
1017 <                    q.next = null;
1016 >                while (b.result == null && !b.tryPushStack(q))
1017 >                    q.lazySetNext(null); // clear on failure
1018              }
1019          }
1020      }
# Line 1265 | Line 1296 | public class CompletableFuture<T> implem
1296      final void orpush(CompletableFuture<?> b, BiCompletion<?,?,?> c) {
1297          if (c != null) {
1298              while ((b == null || b.result == null) && result == null) {
1299 <                if (casStack(c.next = stack, c)) {
1299 >                if (tryPushStack(c)) {
1300                      if (b != null && b != this && b.result == null) {
1301                          Completion q = new CoCompletion(c);
1302                          while (result == null && b.result == null &&
1303 <                               !b.casStack(q.next = b.stack, q))
1304 <                            q.next = null;
1303 >                               !b.tryPushStack(q))
1304 >                            q.lazySetNext(null); // clear on failure
1305                      }
1306                      break;
1307                  }
1308 <                c.next = null;
1308 >                c.lazySetNext(null); // clear on failure
1309              }
1310          }
1311      }
# Line 1660 | Line 1691 | public class CompletableFuture<T> implem
1691              else if (q == null)
1692                  q = new Signaller(interruptible, 0L, 0L);
1693              else if (!queued)
1694 <                queued = casStack(q.next = stack, q);
1694 >                queued = tryPushStack(q);
1695              else if (interruptible && q.interruptControl < 0) {
1696                  q.thread = null;
1697                  cleanStack();
# Line 1702 | Line 1733 | public class CompletableFuture<T> implem
1733          Object r;
1734          while ((r = result) == null) {
1735              if (!queued)
1736 <                queued = casStack(q.next = stack, q);
1736 >                queued = tryPushStack(q);
1737              else if (q.interruptControl < 0 || q.nanos <= 0L) {
1738                  q.thread = null;
1739                  cleanStack();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines