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