5 |
|
*/ |
6 |
|
|
7 |
|
import static java.util.concurrent.TimeUnit.MILLISECONDS; |
8 |
– |
import static java.util.concurrent.TimeUnit.SECONDS; |
8 |
|
|
9 |
|
import java.util.HashSet; |
10 |
|
import java.util.concurrent.CancellationException; |
22 |
|
public class CountedCompleterTest extends JSR166TestCase { |
23 |
|
|
24 |
|
public static void main(String[] args) { |
25 |
< |
junit.textui.TestRunner.run(suite()); |
25 |
> |
main(suite(), args); |
26 |
|
} |
27 |
|
|
28 |
|
public static Test suite() { |
48 |
|
} |
49 |
|
|
50 |
|
private void testInvokeOnPool(ForkJoinPool pool, ForkJoinTask a) { |
51 |
< |
try { |
51 |
> |
try (PoolCleaner cleaner = cleaner(pool)) { |
52 |
|
assertFalse(a.isDone()); |
53 |
|
assertFalse(a.isCompletedNormally()); |
54 |
|
assertFalse(a.isCompletedAbnormally()); |
64 |
|
assertFalse(a.isCancelled()); |
65 |
|
assertNull(a.getException()); |
66 |
|
assertNull(a.getRawResult()); |
68 |
– |
} finally { |
69 |
– |
joinPool(pool); |
67 |
|
} |
68 |
|
} |
69 |
|
|
76 |
|
assertNull(a.getRawResult()); |
77 |
|
|
78 |
|
try { |
79 |
< |
a.get(0L, SECONDS); |
79 |
> |
a.get(randomExpiredTimeout(), randomTimeUnit()); |
80 |
|
shouldThrow(); |
81 |
|
} catch (TimeoutException success) { |
82 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
92 |
|
|
93 |
|
{ |
94 |
|
Thread.currentThread().interrupt(); |
95 |
< |
long t0 = System.nanoTime(); |
95 |
> |
long startTime = System.nanoTime(); |
96 |
|
assertNull(a.join()); |
97 |
< |
assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); |
97 |
> |
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); |
98 |
|
Thread.interrupted(); |
99 |
|
} |
100 |
|
|
101 |
|
{ |
102 |
|
Thread.currentThread().interrupt(); |
103 |
< |
long t0 = System.nanoTime(); |
103 |
> |
long startTime = System.nanoTime(); |
104 |
|
a.quietlyJoin(); // should be no-op |
105 |
< |
assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); |
105 |
> |
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); |
106 |
|
Thread.interrupted(); |
107 |
|
} |
108 |
|
|
109 |
|
assertFalse(a.cancel(false)); |
110 |
|
assertFalse(a.cancel(true)); |
111 |
+ |
|
112 |
+ |
Object v1 = null, v2 = null; |
113 |
|
try { |
114 |
< |
assertNull(a.get()); |
115 |
< |
} catch (Throwable fail) { threadUnexpectedException(fail); } |
117 |
< |
try { |
118 |
< |
assertNull(a.get(5L, SECONDS)); |
114 |
> |
v1 = a.get(); |
115 |
> |
v2 = a.get(randomTimeout(), randomTimeUnit()); |
116 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
117 |
+ |
assertNull(v1); |
118 |
+ |
assertNull(v2); |
119 |
|
} |
120 |
|
|
121 |
|
void checkCancelled(CountedCompleter a) { |
137 |
|
Thread.interrupted(); |
138 |
|
|
139 |
|
{ |
140 |
< |
long t0 = System.nanoTime(); |
140 |
> |
long startTime = System.nanoTime(); |
141 |
|
a.quietlyJoin(); // should be no-op |
142 |
< |
assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); |
142 |
> |
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); |
143 |
|
} |
144 |
|
|
145 |
|
try { |
149 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
150 |
|
|
151 |
|
try { |
152 |
< |
a.get(5L, SECONDS); |
152 |
> |
a.get(randomTimeout(), randomTimeUnit()); |
153 |
|
shouldThrow(); |
154 |
|
} catch (CancellationException success) { |
155 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
175 |
|
Thread.interrupted(); |
176 |
|
|
177 |
|
{ |
178 |
< |
long t0 = System.nanoTime(); |
178 |
> |
long startTime = System.nanoTime(); |
179 |
|
a.quietlyJoin(); // should be no-op |
180 |
< |
assertTrue(millisElapsedSince(t0) < SMALL_DELAY_MS); |
180 |
> |
assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); |
181 |
|
} |
182 |
|
|
183 |
|
try { |
188 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
189 |
|
|
190 |
|
try { |
191 |
< |
a.get(5L, SECONDS); |
191 |
> |
a.get(randomTimeout(), randomTimeUnit()); |
192 |
|
shouldThrow(); |
193 |
|
} catch (ExecutionException success) { |
194 |
|
assertSame(t.getClass(), success.getCause().getClass()); |
211 |
|
final AtomicInteger onCompletionN = new AtomicInteger(0); |
212 |
|
final AtomicInteger onExceptionalCompletionN = new AtomicInteger(0); |
213 |
|
final AtomicInteger setRawResultN = new AtomicInteger(0); |
214 |
< |
final AtomicReference<Object> rawResult = new AtomicReference<Object>(null); |
214 |
> |
final AtomicReference<Object> rawResult = new AtomicReference<>(null); |
215 |
|
int computeN() { return computeN.get(); } |
216 |
|
int onCompletionN() { return onCompletionN.get(); } |
217 |
|
int onExceptionalCompletionN() { return onExceptionalCompletionN.get(); } |
279 |
|
final class NoopCC extends CheckedCC { |
280 |
|
NoopCC() { super(); } |
281 |
|
NoopCC(CountedCompleter p) { super(p); } |
282 |
+ |
NoopCC(CountedCompleter p, int initialPendingCount) { |
283 |
+ |
super(p, initialPendingCount); |
284 |
+ |
} |
285 |
|
protected void realCompute() {} |
286 |
|
} |
287 |
|
|
300 |
|
void testComplete(NoopCC cc, Object x, int pendingCount) { |
301 |
|
cc.setPendingCount(pendingCount); |
302 |
|
cc.checkCompletes(x); |
303 |
+ |
assertEquals(pendingCount, cc.getPendingCount()); |
304 |
|
} |
305 |
|
|
306 |
|
/** |
314 |
|
} |
315 |
|
|
316 |
|
/** |
317 |
< |
* completeExceptionally(null) throws NullPointerException |
317 |
> |
* completeExceptionally(null) surprisingly has the same effect as |
318 |
> |
* completeExceptionally(new RuntimeException()) |
319 |
|
*/ |
320 |
|
public void testCompleteExceptionally_null() { |
321 |
+ |
NoopCC a = new NoopCC(); |
322 |
+ |
a.completeExceptionally(null); |
323 |
|
try { |
324 |
< |
new NoopCC() |
319 |
< |
.checkCompletesExceptionally(null); |
324 |
> |
a.invoke(); |
325 |
|
shouldThrow(); |
326 |
< |
} catch (NullPointerException success) {} |
326 |
> |
} catch (RuntimeException success) { |
327 |
> |
assertSame(success.getClass(), RuntimeException.class); |
328 |
> |
assertNull(success.getCause()); |
329 |
> |
a.checkCompletedExceptionally(success); |
330 |
> |
} |
331 |
|
} |
332 |
|
|
333 |
|
/** |
336 |
|
public void testSetPendingCount() { |
337 |
|
NoopCC a = new NoopCC(); |
338 |
|
assertEquals(0, a.getPendingCount()); |
339 |
< |
a.setPendingCount(1); |
340 |
< |
assertEquals(1, a.getPendingCount()); |
341 |
< |
a.setPendingCount(27); |
342 |
< |
assertEquals(27, a.getPendingCount()); |
339 |
> |
int[] vals = { |
340 |
> |
-1, 0, 1, |
341 |
> |
Integer.MIN_VALUE, |
342 |
> |
Integer.MAX_VALUE, |
343 |
> |
}; |
344 |
> |
for (int val : vals) { |
345 |
> |
a.setPendingCount(val); |
346 |
> |
assertEquals(val, a.getPendingCount()); |
347 |
> |
} |
348 |
|
} |
349 |
|
|
350 |
|
/** |
357 |
|
assertEquals(1, a.getPendingCount()); |
358 |
|
a.addToPendingCount(27); |
359 |
|
assertEquals(28, a.getPendingCount()); |
360 |
+ |
a.addToPendingCount(-28); |
361 |
+ |
assertEquals(0, a.getPendingCount()); |
362 |
|
} |
363 |
|
|
364 |
|
/** |
365 |
|
* decrementPendingCountUnlessZero decrements reported pending |
366 |
|
* count unless zero |
367 |
|
*/ |
368 |
< |
public void testDecrementPendingCount() { |
369 |
< |
NoopCC a = new NoopCC(); |
370 |
< |
assertEquals(0, a.getPendingCount()); |
371 |
< |
a.addToPendingCount(1); |
368 |
> |
public void testDecrementPendingCountUnlessZero() { |
369 |
> |
NoopCC a = new NoopCC(null, 2); |
370 |
> |
assertEquals(2, a.getPendingCount()); |
371 |
> |
assertEquals(2, a.decrementPendingCountUnlessZero()); |
372 |
|
assertEquals(1, a.getPendingCount()); |
373 |
< |
a.decrementPendingCountUnlessZero(); |
373 |
> |
assertEquals(1, a.decrementPendingCountUnlessZero()); |
374 |
|
assertEquals(0, a.getPendingCount()); |
375 |
< |
a.decrementPendingCountUnlessZero(); |
375 |
> |
assertEquals(0, a.decrementPendingCountUnlessZero()); |
376 |
|
assertEquals(0, a.getPendingCount()); |
377 |
+ |
a.setPendingCount(-1); |
378 |
+ |
assertEquals(-1, a.decrementPendingCountUnlessZero()); |
379 |
+ |
assertEquals(-2, a.getPendingCount()); |
380 |
|
} |
381 |
|
|
382 |
|
/** |
500 |
|
} |
501 |
|
|
502 |
|
/** |
503 |
< |
* quietlyCompleteRoot completes root task |
503 |
> |
* quietlyCompleteRoot completes root task and only root task |
504 |
|
*/ |
505 |
|
public void testQuietlyCompleteRoot() { |
506 |
|
NoopCC a = new NoopCC(); |
703 |
|
CCF f = new LCCF(8); |
704 |
|
assertSame(f, f.fork()); |
705 |
|
try { |
706 |
< |
f.get(5L, null); |
706 |
> |
f.get(randomTimeout(), null); |
707 |
|
shouldThrow(); |
708 |
|
} catch (NullPointerException success) {} |
709 |
|
}}; |
735 |
|
CCF f = new LCCF(8); |
736 |
|
assertSame(f, f.fork()); |
737 |
|
helpQuiesce(); |
738 |
+ |
while (!f.isDone()) // wait out race |
739 |
+ |
; |
740 |
|
assertEquals(21, f.number); |
741 |
|
assertEquals(0, getQueuedTaskCount()); |
742 |
|
checkCompletedNormally(f); |
1427 |
|
CCF f = new LCCF(8); |
1428 |
|
assertSame(f, f.fork()); |
1429 |
|
try { |
1430 |
< |
f.get(5L, null); |
1430 |
> |
f.get(randomTimeout(), null); |
1431 |
|
shouldThrow(); |
1432 |
|
} catch (NullPointerException success) {} |
1433 |
|
}}; |