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.176 by jsr166, Tue Sep 29 04:08:26 2015 UTC vs.
Revision 1.177 by dl, Sat Oct 3 15:55:09 2015 UTC

# Line 1678 | Line 1678 | public class CompletableFuture<T> implem
1678          implements ForkJoinPool.ManagedBlocker {
1679          long nanos;                    // remaining wait time if timed
1680          final long deadline;           // non-zero if timed
1681 <        volatile int interruptControl; // > 0: interruptible, < 0: interrupted
1681 >        final boolean interruptible;
1682 >        boolean interrupted;
1683          volatile Thread thread;
1684  
1685          Signaller(boolean interruptible, long nanos, long deadline) {
1686              this.thread = Thread.currentThread();
1687 <            this.interruptControl = interruptible ? 1 : 0;
1687 >            this.interruptible = interruptible;
1688              this.nanos = nanos;
1689              this.deadline = deadline;
1690          }
# Line 1696 | Line 1697 | public class CompletableFuture<T> implem
1697              return null;
1698          }
1699          public boolean isReleasable() {
1700 <            if (thread == null)
1701 <                return true;
1702 <            if (Thread.interrupted()) {
1703 <                int i = interruptControl;
1704 <                interruptControl = -1;
1705 <                if (i > 0)
1706 <                    return true;
1706 <            }
1707 <            if (deadline != 0L &&
1708 <                (nanos <= 0L || (nanos = deadline - System.nanoTime()) <= 0L)) {
1709 <                thread = null;
1710 <                return true;
1711 <            }
1712 <            return false;
1700 >            if (Thread.interrupted())
1701 >                interrupted = true;
1702 >            return ((interrupted && interruptible) ||
1703 >                    (deadline != 0L &&
1704 >                     (nanos <= 0L ||
1705 >                      (nanos = deadline - System.nanoTime()) <= 0L)) ||
1706 >                    thread == null);
1707          }
1708          public boolean block() {
1709 <            if (isReleasable())
1710 <                return true;
1711 <            else if (deadline == 0L)
1712 <                LockSupport.park(this);
1713 <            else if (nanos > 0L)
1714 <                LockSupport.parkNanos(this, nanos);
1715 <            return isReleasable();
1709 >            while (!isReleasable()) {
1710 >                if (deadline == 0L)
1711 >                    LockSupport.park(this);
1712 >                else
1713 >                    LockSupport.parkNanos(this, nanos);
1714 >            }
1715 >            return true;
1716          }
1717          final boolean isLive() { return thread != null; }
1718      }
# Line 1744 | Line 1738 | public class CompletableFuture<T> implem
1738                  q = new Signaller(interruptible, 0L, 0L);
1739              else if (!queued)
1740                  queued = tryPushStack(q);
1741 <            else if (interruptible && q.interruptControl < 0) {
1748 <                q.thread = null;
1749 <                cleanStack();
1750 <                return null;
1751 <            }
1752 <            else if (q.thread != null && result == null) {
1741 >            else {
1742                  try {
1743                      ForkJoinPool.managedBlock(q);
1744                  } catch (InterruptedException ie) {
1745 <                    q.interruptControl = -1;
1745 >                    q.interrupted = true;
1746                  }
1747 +                if (q.interrupted && interruptible)
1748 +                    break;
1749              }
1750          }
1751          if (q != null) {
1752              q.thread = null;
1753 <            if (q.interruptControl < 0) {
1753 >            if (q.interrupted) {
1754                  if (interruptible)
1755 <                    r = null; // report interruption
1755 >                    cleanStack();
1756                  else
1757                      Thread.currentThread().interrupt();
1758              }
1759          }
1760 <        postComplete();
1760 >        if (r != null)
1761 >            postComplete();
1762          return r;
1763      }
1764  
# Line 1777 | Line 1769 | public class CompletableFuture<T> implem
1769      private Object timedGet(long nanos) throws TimeoutException {
1770          if (Thread.interrupted())
1771              return null;
1772 <        if (nanos <= 0L)
1773 <            throw new TimeoutException();
1774 <        long d = System.nanoTime() + nanos;
1775 <        Signaller q = new Signaller(true, nanos, d == 0L ? 1L : d); // avoid 0
1776 <        boolean queued = false;
1777 <        Object r;
1778 <        // We intentionally don't spin here (as waitingGet does) because
1779 <        // the call to nanoTime() above acts much like a spin.
1780 <        while ((r = result) == null) {
1781 <            if (!queued)
1782 <                queued = tryPushStack(q);
1783 <            else if (q.interruptControl < 0 || q.nanos <= 0L) {
1784 <                q.thread = null;
1785 <                cleanStack();
1786 <                if (q.interruptControl < 0)
1787 <                    return null;
1788 <                throw new TimeoutException();
1789 <            }
1790 <            else if (q.thread != null && result == null) {
1791 <                try {
1792 <                    ForkJoinPool.managedBlock(q);
1801 <                } catch (InterruptedException ie) {
1802 <                    q.interruptControl = -1;
1772 >        if (nanos > 0L) {
1773 >            long d = System.nanoTime() + nanos;
1774 >            long deadline = (d == 0L) ? 1L : d; // avoid 0
1775 >            Signaller q = null;
1776 >            boolean queued = false;
1777 >            Object r;
1778 >            while ((r = result) == null) { // similar to untimed, without spins
1779 >                if (q == null)
1780 >                    q = new Signaller(true, nanos, deadline);
1781 >                else if (!queued)
1782 >                    queued = tryPushStack(q);
1783 >                else if (q.nanos <= 0)
1784 >                    break;
1785 >                else {
1786 >                    try {
1787 >                        ForkJoinPool.managedBlock(q);
1788 >                    } catch (InterruptedException ie) {
1789 >                        q.interrupted = true;
1790 >                    }
1791 >                    if (q.interrupted)
1792 >                        break;
1793                  }
1794              }
1795 +            if (q != null)
1796 +                q.thread = null;
1797 +            if (r != null)
1798 +                postComplete();
1799 +            else
1800 +                cleanStack();
1801 +            if (r != null || (q != null && q.interrupted))
1802 +                return r;
1803          }
1804 <        if (q.interruptControl < 0)
1807 <            r = null;
1808 <        q.thread = null;
1809 <        postComplete();
1810 <        return r;
1804 >        throw new TimeoutException();
1805      }
1806  
1807      /* ------------- public methods -------------- */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines