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

Comparing jsr166/src/main/java/util/concurrent/FutureTask.java (file contents):
Revision 1.105 by jsr166, Thu Aug 21 01:56:10 2014 UTC vs.
Revision 1.106 by jsr166, Fri Aug 22 03:30:56 2014 UTC

# Line 364 | Line 364 | public class FutureTask<V> implements Ru
364       */
365      private int awaitDone(boolean timed, long nanos)
366          throws InterruptedException {
367 <        final long deadline = timed ? System.nanoTime() + nanos : 0L;
367 >        // The code below is very delicate, to achieve these goals:
368 >        // - call nanoTime exactly once for each call to park
369 >        // - if nanos <= 0, return promptly without allocation or nanoTime
370 >        // - if nanos == Long.MIN_VALUE, don't underflow
371 >        // - if nanos == Long.MAX_VALUE, and nanoTime is non-monotonic
372 >        //   and we suffer a spurious wakeup, we will do no worse than
373 >        //   to park-spin for a while
374 >        long startTime = 0L;    // Special value 0L means not yet parked
375          WaitNode q = null;
376          boolean queued = false;
377          for (;;) {
# Line 381 | Line 388 | public class FutureTask<V> implements Ru
388              }
389              else if (s == COMPLETING) // cannot time out yet
390                  Thread.yield();
391 <            else if (q == null)
391 >            else if (q == null) {
392 >                if (timed && nanos <= 0L)
393 >                    return s;
394                  q = new WaitNode();
395 +            }
396              else if (!queued)
397                  queued = U.compareAndSwapObject(this, WAITERS,
398                                                  q.next = waiters, q);
399              else if (timed) {
400 <                nanos = deadline - System.nanoTime();
401 <                if (nanos <= 0L) {
402 <                    removeWaiter(q);
403 <                    return state;
400 >                final long parkNanos;
401 >                if (startTime == 0L) { // first time
402 >                    startTime = System.nanoTime();
403 >                    if (startTime == 0L)
404 >                        startTime = 1L;
405 >                    parkNanos = nanos;
406 >                } else {
407 >                    long elapsed = System.nanoTime() - startTime;
408 >                    if (elapsed >= nanos) {
409 >                        removeWaiter(q);
410 >                        return state;
411 >                    }
412 >                    parkNanos = nanos - elapsed;
413                  }
414 <                LockSupport.parkNanos(this, nanos);
414 >                LockSupport.parkNanos(this, parkNanos);
415              }
416              else
417                  LockSupport.park(this);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines