8313290: Misleading exception message from STS.Subtask::get when task forked after shutdown
Reviewed-by: psandoz
This commit is contained in:
parent
febc34dd28
commit
ed0f75f266
@ -576,8 +576,6 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SubtaskImpl<U> subtask = new SubtaskImpl<>(this, task, round);
|
SubtaskImpl<U> subtask = new SubtaskImpl<>(this, task, round);
|
||||||
boolean started = false;
|
|
||||||
|
|
||||||
if (s < SHUTDOWN) {
|
if (s < SHUTDOWN) {
|
||||||
// create thread to run task
|
// create thread to run task
|
||||||
Thread thread = factory.newThread(subtask);
|
Thread thread = factory.newThread(subtask);
|
||||||
@ -588,15 +586,14 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
|||||||
// attempt to start the thread
|
// attempt to start the thread
|
||||||
try {
|
try {
|
||||||
flock.start(thread);
|
flock.start(thread);
|
||||||
started = true;
|
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
// shutdown by another thread, or underlying flock is shutdown due
|
// shutdown by another thread, or underlying flock is shutdown due
|
||||||
// to unstructured use
|
// to unstructured use
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// force owner to join if thread started
|
// force owner to join if this is the first fork in the round
|
||||||
if (started && Thread.currentThread() == flock.owner() && round > forkRound) {
|
if (Thread.currentThread() == flock.owner() && round > forkRound) {
|
||||||
forkRound = round;
|
forkRound = round;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -939,7 +936,8 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
|||||||
T r = (T) result;
|
T r = (T) result;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Subtask not completed or did not complete successfully");
|
throw new IllegalStateException(
|
||||||
|
"Result is unavailable or subtask did not complete successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -949,7 +947,8 @@ public class StructuredTaskScope<T> implements AutoCloseable {
|
|||||||
if (result instanceof AltResult alt && alt.state() == State.FAILED) {
|
if (result instanceof AltResult alt && alt.state() == State.FAILED) {
|
||||||
return alt.exception();
|
return alt.exception();
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Subtask not completed or did not complete with exception");
|
throw new IllegalStateException(
|
||||||
|
"Exception is unavailable or subtask did not complete with exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -279,6 +279,7 @@ class StructuredTaskScopeTest {
|
|||||||
executed.set(true);
|
executed.set(true);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
scope.join();
|
||||||
assertEquals(Subtask.State.UNAVAILABLE, subtask.state());
|
assertEquals(Subtask.State.UNAVAILABLE, subtask.state());
|
||||||
assertThrows(IllegalStateException.class, subtask::get);
|
assertThrows(IllegalStateException.class, subtask::get);
|
||||||
assertThrows(IllegalStateException.class, subtask::exception);
|
assertThrows(IllegalStateException.class, subtask::exception);
|
||||||
@ -673,22 +674,6 @@ class StructuredTaskScopeTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test that shutdown prevents new threads from starting.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
void testShutdownWithFork() throws Exception {
|
|
||||||
ThreadFactory factory = task -> null;
|
|
||||||
try (var scope = new StructuredTaskScope<Object>(null, factory)) {
|
|
||||||
scope.shutdown();
|
|
||||||
// should not invoke the ThreadFactory to create thread
|
|
||||||
Subtask<Void> subtask = scope.fork(() -> null);
|
|
||||||
assertEquals(Subtask.State.UNAVAILABLE, subtask.state());
|
|
||||||
assertThrows(IllegalStateException.class, subtask::get);
|
|
||||||
assertThrows(IllegalStateException.class, subtask::exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that shutdown interrupts unfinished subtasks.
|
* Test that shutdown interrupts unfinished subtasks.
|
||||||
*/
|
*/
|
||||||
@ -1377,6 +1362,7 @@ class StructuredTaskScopeTest {
|
|||||||
|
|
||||||
// fork after shutdown
|
// fork after shutdown
|
||||||
Subtask<Void> subtask = scope.fork(task);
|
Subtask<Void> subtask = scope.fork(task);
|
||||||
|
scope.join();
|
||||||
assertEquals(task, subtask.task());
|
assertEquals(task, subtask.task());
|
||||||
assertEquals(Subtask.State.UNAVAILABLE, subtask.state());
|
assertEquals(Subtask.State.UNAVAILABLE, subtask.state());
|
||||||
assertThrows(IllegalStateException.class, subtask::get);
|
assertThrows(IllegalStateException.class, subtask::get);
|
||||||
|
Loading…
Reference in New Issue
Block a user