376 |
|
WaitNode q = null; |
377 |
|
boolean queued = false; |
378 |
|
for (;;) { |
379 |
– |
if (Thread.interrupted()) { |
380 |
– |
removeWaiter(q); |
381 |
– |
throw new InterruptedException(); |
382 |
– |
} |
383 |
– |
|
379 |
|
int s = state; |
380 |
|
if (s > COMPLETING) { |
381 |
|
if (q != null) |
382 |
|
q.thread = null; |
383 |
|
return s; |
384 |
|
} |
385 |
< |
else if (s == COMPLETING) // cannot time out yet |
385 |
> |
else if (s == COMPLETING) |
386 |
> |
// We may have already promised (via isDone) that we are done |
387 |
> |
// so never return empty-handed or throw InterruptedException |
388 |
|
Thread.yield(); |
389 |
+ |
else if (Thread.interrupted()) { |
390 |
+ |
removeWaiter(q); |
391 |
+ |
throw new InterruptedException(); |
392 |
+ |
} |
393 |
|
else if (q == null) { |
394 |
|
if (timed && nanos <= 0L) |
395 |
|
return s; |
413 |
|
} |
414 |
|
parkNanos = nanos - elapsed; |
415 |
|
} |
416 |
< |
LockSupport.parkNanos(this, parkNanos); |
416 |
> |
// nanoTime may be slow; recheck before parking |
417 |
> |
if (state < COMPLETING) |
418 |
> |
LockSupport.parkNanos(this, parkNanos); |
419 |
|
} |
420 |
|
else |
421 |
|
LockSupport.park(this); |
455 |
|
} |
456 |
|
|
457 |
|
// Unsafe mechanics |
458 |
< |
private static final sun.misc.Unsafe U; |
458 |
> |
private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); |
459 |
|
private static final long STATE; |
460 |
|
private static final long RUNNER; |
461 |
|
private static final long WAITERS; |
462 |
|
static { |
463 |
|
try { |
464 |
< |
U = sun.misc.Unsafe.getUnsafe(); |
465 |
< |
Class<?> k = FutureTask.class; |
466 |
< |
STATE = U.objectFieldOffset(k.getDeclaredField("state")); |
467 |
< |
RUNNER = U.objectFieldOffset(k.getDeclaredField("runner")); |
468 |
< |
WAITERS = U.objectFieldOffset(k.getDeclaredField("waiters")); |
464 |
> |
STATE = U.objectFieldOffset |
465 |
> |
(FutureTask.class.getDeclaredField("state")); |
466 |
> |
RUNNER = U.objectFieldOffset |
467 |
> |
(FutureTask.class.getDeclaredField("runner")); |
468 |
> |
WAITERS = U.objectFieldOffset |
469 |
> |
(FutureTask.class.getDeclaredField("waiters")); |
470 |
|
} catch (Exception e) { |
471 |
|
throw new Error(e); |
472 |
|
} |