183 |
|
private static final int EXCEPTIONAL = 0xa0000000; |
184 |
|
private static final int SIGNAL_MASK = 0x0000ffff; |
185 |
|
private static final int INTERNAL_SIGNAL_MASK = 0x00007fff; |
186 |
< |
private static final int EXTERNAL_SIGNAL = 0x00008000; |
186 |
> |
private static final int EXTERNAL_SIGNAL = 0x00008000; |
187 |
|
|
188 |
|
/** |
189 |
|
* Table of exceptions thrown by tasks, to enable reporting by |
256 |
|
*/ |
257 |
|
final int requestSignal() { |
258 |
|
int s; |
259 |
< |
do {} while ((s = status) >= 0 && |
259 |
> |
do {} while ((s = status) >= 0 && |
260 |
|
!UNSAFE.compareAndSwapInt(this, statusOffset, s, s + 1)); |
261 |
|
return s; |
262 |
|
} |
263 |
< |
|
263 |
> |
|
264 |
|
/** |
265 |
|
* Sets external signal request unless already done. |
266 |
|
* |
268 |
|
*/ |
269 |
|
private int requestExternalSignal() { |
270 |
|
int s; |
271 |
< |
do {} while ((s = status) >= 0 && |
272 |
< |
!UNSAFE.compareAndSwapInt(this, statusOffset, |
271 |
> |
do {} while ((s = status) >= 0 && |
272 |
> |
!UNSAFE.compareAndSwapInt(this, statusOffset, |
273 |
|
s, s | EXTERNAL_SIGNAL)); |
274 |
|
return s; |
275 |
|
} |
287 |
|
private void awaitDone(ForkJoinWorkerThread w) { |
288 |
|
if (status >= 0) { |
289 |
|
w.pool.preJoin(this); |
290 |
< |
while (status >= 0) { |
290 |
> |
while (status >= 0) { |
291 |
|
try { // minimize lock scope |
292 |
|
synchronized(this) { |
293 |
< |
if (status >= 0) |
294 |
< |
wait(); |
293 |
> |
if (status >= 0) |
294 |
> |
wait(); |
295 |
|
else { // help release; also helps avoid lock-biasing |
296 |
|
notifyAll(); |
297 |
|
break; |
313 |
|
while (status >= 0) { |
314 |
|
try { |
315 |
|
synchronized(this) { |
316 |
< |
if (status >= 0) |
317 |
< |
wait(); |
316 |
> |
if (status >= 0) |
317 |
> |
wait(); |
318 |
|
else { |
319 |
|
notifyAll(); |
320 |
|
break; |
350 |
|
} |
351 |
|
else { |
352 |
|
int s; // adjust running count on timeout |
353 |
< |
while ((s = status) >= 0 && |
353 |
> |
while ((s = status) >= 0 && |
354 |
|
(s & INTERNAL_SIGNAL_MASK) != 0) { |
355 |
< |
if (UNSAFE.compareAndSwapInt(this, statusOffset, |
355 |
> |
if (UNSAFE.compareAndSwapInt(this, statusOffset, |
356 |
|
s, s - 1)) { |
357 |
|
pool.updateRunningCount(1); |
358 |
|
break; |
682 |
|
private void cancelIfTerminating() { |
683 |
|
Thread t = Thread.currentThread(); |
684 |
|
if ((t instanceof ForkJoinWorkerThread) && |
685 |
< |
((ForkJoinWorkerThread) t).isTerminating()) { |
685 |
> |
((ForkJoinWorkerThread) t).isTerminating()) { |
686 |
|
try { |
687 |
|
cancel(false); |
688 |
|
} catch (Throwable ignore) { |
778 |
|
quietlyJoin(); |
779 |
|
return reportFutureResult(); |
780 |
|
} |
781 |
< |
|
781 |
> |
|
782 |
|
public final V get(long timeout, TimeUnit unit) |
783 |
|
throws InterruptedException, ExecutionException, TimeoutException { |
784 |
|
long nanos = unit.toNanos(timeout); |
830 |
|
public final void quietlyHelpJoin() { |
831 |
|
ForkJoinWorkerThread w = (ForkJoinWorkerThread) Thread.currentThread(); |
832 |
|
if (!w.unpushTask(this) || !tryExec()) { |
833 |
< |
while (status >= 0) { |
834 |
< |
ForkJoinTask<?> t = w.scanWhileJoining(this); |
835 |
< |
if (t == null) { |
836 |
< |
if (status >= 0) |
837 |
< |
awaitDone(w); |
838 |
< |
break; |
833 |
> |
for (;;) { |
834 |
> |
ForkJoinTask<?> t; |
835 |
> |
if (status < 0) |
836 |
> |
return; |
837 |
> |
else if ((t = w.scanWhileJoining(this)) != null) |
838 |
> |
t.tryExec(); |
839 |
> |
else if (status < 0) |
840 |
> |
return; |
841 |
> |
else if (w.pool.preBlockHelpingJoin(this)) { |
842 |
> |
while (status >= 0) { // variant of awaitDone |
843 |
> |
try { |
844 |
> |
synchronized(this) { |
845 |
> |
if (status >= 0) |
846 |
> |
wait(); |
847 |
> |
else { |
848 |
> |
notifyAll(); |
849 |
> |
break; |
850 |
> |
} |
851 |
> |
} |
852 |
> |
} catch (InterruptedException ie) { |
853 |
> |
cancelIfTerminating(); |
854 |
> |
} |
855 |
> |
} |
856 |
> |
return; |
857 |
|
} |
840 |
– |
t.tryExec(); |
858 |
|
} |
859 |
|
} |
860 |
|
} |