8173817: StackOverflowError in "process reaper" thread

Switch to inner class to avoid lambda stack overhead in ProcessReaper

Reviewed-by: dholmes, martin
This commit is contained in:
Roger Riggs 2017-08-22 09:41:58 -04:00
parent 312f813dbb
commit 9c6245db87

View File

@ -132,34 +132,37 @@ final class ProcessHandleImpl implements ProcessHandle {
// newCompletion has just been installed successfully // newCompletion has just been installed successfully
completion = newCompletion; completion = newCompletion;
// spawn a thread to wait for and deliver the exit value // spawn a thread to wait for and deliver the exit value
processReaperExecutor.execute(() -> { processReaperExecutor.execute(new Runnable() {
int exitValue = waitForProcessExit0(pid, shouldReap); // Use inner class to avoid lambda stack overhead
if (exitValue == NOT_A_CHILD) { public void run() {
// pid not alive or not a child of this process int exitValue = waitForProcessExit0(pid, shouldReap);
// If it is alive wait for it to terminate if (exitValue == NOT_A_CHILD) {
long sleep = 300; // initial milliseconds to sleep // pid not alive or not a child of this process
int incr = 30; // increment to the sleep time // If it is alive wait for it to terminate
long sleep = 300; // initial milliseconds to sleep
int incr = 30; // increment to the sleep time
long startTime = isAlive0(pid); long startTime = isAlive0(pid);
long origStart = startTime; long origStart = startTime;
while (startTime >= 0) { while (startTime >= 0) {
try { try {
Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec
sleep += incr; sleep += incr;
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
// ignore and retry // ignore and retry
} }
startTime = isAlive0(pid); // recheck if is alive startTime = isAlive0(pid); // recheck if is alive
if (origStart > 0 && startTime != origStart) { if (origStart > 0 && startTime != origStart) {
// start time changed, pid is not the same process // start time changed, pid is not the same process
break; break;
}
} }
exitValue = 0;
} }
exitValue = 0; newCompletion.complete(exitValue);
// remove from cache afterwards
completions.remove(pid, newCompletion);
} }
newCompletion.complete(exitValue);
// remove from cache afterwards
completions.remove(pid, newCompletion);
}); });
} }
} }