|
@@ -21,6 +21,7 @@ import java.io.BufferedReader;
|
|
import java.io.File;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.io.InputStreamReader;
|
|
import java.io.InputStreamReader;
|
|
|
|
+import java.io.InputStream;
|
|
import java.util.Arrays;
|
|
import java.util.Arrays;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
import java.util.Timer;
|
|
import java.util.Timer;
|
|
@@ -511,7 +512,17 @@ abstract public class Shell {
|
|
}
|
|
}
|
|
// close the input stream
|
|
// close the input stream
|
|
try {
|
|
try {
|
|
- inReader.close();
|
|
|
|
|
|
+ // JDK 7 tries to automatically drain the input streams for us
|
|
|
|
+ // when the process exits, but since close is not synchronized,
|
|
|
|
+ // it creates a race if we close the stream first and the same
|
|
|
|
+ // fd is recycled. the stream draining thread will attempt to
|
|
|
|
+ // drain that fd!! it may block, OOM, or cause bizarre behavior
|
|
|
|
+ // see: https://bugs.openjdk.java.net/browse/JDK-8024521
|
|
|
|
+ // issue is fixed in build 7u60
|
|
|
|
+ InputStream stdout = process.getInputStream();
|
|
|
|
+ synchronized (stdout) {
|
|
|
|
+ inReader.close();
|
|
|
|
+ }
|
|
} catch (IOException ioe) {
|
|
} catch (IOException ioe) {
|
|
LOG.warn("Error while closing the input stream", ioe);
|
|
LOG.warn("Error while closing the input stream", ioe);
|
|
}
|
|
}
|
|
@@ -524,7 +535,10 @@ abstract public class Shell {
|
|
LOG.warn("Interrupted while joining errThread");
|
|
LOG.warn("Interrupted while joining errThread");
|
|
}
|
|
}
|
|
try {
|
|
try {
|
|
- errReader.close();
|
|
|
|
|
|
+ InputStream stderr = process.getErrorStream();
|
|
|
|
+ synchronized (stderr) {
|
|
|
|
+ errReader.close();
|
|
|
|
+ }
|
|
} catch (IOException ioe) {
|
|
} catch (IOException ioe) {
|
|
LOG.warn("Error while closing the error stream", ioe);
|
|
LOG.warn("Error while closing the error stream", ioe);
|
|
}
|
|
}
|