Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java
Original file line number Diff line number Diff line change
Expand Up @@ -3452,22 +3452,30 @@ private DelayScheduler startDelayScheduler() {
String name = poolName + "-delayScheduler";
if (workerNamePrefix == null)
asyncCommonPool(); // override common parallelism zero
lockRunState();
long isShutdown = lockRunState() & SHUTDOWN;
try {
if ((ds = delayScheduler) == null) {
if (isShutdown == 0L && (ds = delayScheduler) == null) {
ds = delayScheduler = new DelayScheduler(this, name);
start = true;
}
} finally {
unlockRunState();
}
if (start) { // start outside of lock
// exceptions on start passed to (external) callers
SharedThreadContainer ctr;
if ((ctr = container) != null)
ctr.start(ds);
else
ds.start();
try {
if ((ctr = container) != null)
ctr.start(ds);
else
ds.start();
} catch (RuntimeException | Error ex) { // back out
lockRunState();
ds = delayScheduler = null;
unlockRunState();
tryTerminate(false, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reset okay, and the schedule methods will throw REE. The change makes me wonder about the OOME "unable to create new native thread" scenario, should the schedule methods propagate it or throw REE with the OOME as cause?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OOME (not REE) is thrown if the creation fails in the try-finally, which seems best. But if start() throws OOME (or any other Error), I see that we should do the same back-out as with ISE, but rethrow it now vs rely on the the REE in schedule(). I'll adjust accordingly.

if (ex instanceof Error)
throw ex;
}
}
}
return ds;
Expand Down
18 changes: 18 additions & 0 deletions test/jdk/java/util/concurrent/tck/ForkJoinPool20Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -644,4 +644,22 @@ public Boolean realCall() {
}
}

/**
* schedule throws RejectedExecutionException if shutdown before
* first delayed task is submitted
*/
public void testInitialScheduleAfterShutdown() throws InterruptedException {
Runnable r = new NoOpRunnable();
boolean rje = false;
try (final ForkJoinPool p = new ForkJoinPool(1)) {
p.shutdown();
assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
try {
p.schedule(r, 1, MILLISECONDS);
} catch (RejectedExecutionException ok) {
rje = true;
}
}
assertTrue(rje);
}
}