8173817: StackOverflowError in "process reaper" thread
Summary: Switch to inner class to avoid lambda stack overhead in ProcessReaper
Reviewed-by: dholmes, martin
--- a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Tue Aug 22 13:08:15 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Tue Aug 22 09:41:58 2017 -0400
@@ -132,34 +132,37 @@
// newCompletion has just been installed successfully
completion = newCompletion;
// spawn a thread to wait for and deliver the exit value
- processReaperExecutor.execute(() -> {
- int exitValue = waitForProcessExit0(pid, shouldReap);
- if (exitValue == NOT_A_CHILD) {
- // pid not alive or not a child of this process
- // If it is alive wait for it to terminate
- long sleep = 300; // initial milliseconds to sleep
- int incr = 30; // increment to the sleep time
+ processReaperExecutor.execute(new Runnable() {
+ // Use inner class to avoid lambda stack overhead
+ public void run() {
+ int exitValue = waitForProcessExit0(pid, shouldReap);
+ if (exitValue == NOT_A_CHILD) {
+ // pid not alive or not a child of this process
+ // 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 origStart = startTime;
- while (startTime >= 0) {
- try {
- Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec
- sleep += incr;
- } catch (InterruptedException ie) {
- // ignore and retry
+ long startTime = isAlive0(pid);
+ long origStart = startTime;
+ while (startTime >= 0) {
+ try {
+ Thread.sleep(Math.min(sleep, 5000L)); // no more than 5 sec
+ sleep += incr;
+ } catch (InterruptedException ie) {
+ // ignore and retry
+ }
+ startTime = isAlive0(pid); // recheck if is alive
+ if (origStart > 0 && startTime != origStart) {
+ // start time changed, pid is not the same process
+ break;
+ }
}
- startTime = isAlive0(pid); // recheck if is alive
- if (origStart > 0 && startTime != origStart) {
- // start time changed, pid is not the same process
- 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);
});
}
}