8024660: TEST_BUG: java/lang/ProcessBuilder/*IOHandle.java leaving hotspot.log open in fastdebug builds
Reviewed-by: alanb
This commit is contained in:
parent
faec7818a6
commit
fd2c7a3743
@ -35,21 +35,22 @@ import java.io.InputStreamReader;
|
|||||||
|
|
||||||
public class InheritIOEHandle {
|
public class InheritIOEHandle {
|
||||||
private static enum APP {
|
private static enum APP {
|
||||||
B, C;
|
A, B, C;
|
||||||
}
|
}
|
||||||
private static File stopC = new File(".\\StopC.txt");
|
|
||||||
|
private static File stopC = new File("StopC.txt");
|
||||||
private static String SIGNAL = "After call child process";
|
private static String SIGNAL = "After call child process";
|
||||||
private static String JAVA_EXE = System.getProperty("java.home")
|
private static String JAVA_EXE = System.getProperty("java.home")
|
||||||
+ File.separator + "bin"
|
+ File.separator + "bin"
|
||||||
+ File.separator + "java";
|
+ File.separator + "java";
|
||||||
|
|
||||||
private static String[] getCommandArray(String processName) {
|
private static String[] getCommandArray(String processName) {
|
||||||
String[] cmdArray = {
|
String[] cmdArray = {
|
||||||
JAVA_EXE,
|
JAVA_EXE,
|
||||||
"-cp",
|
"-cp",
|
||||||
System.getProperty("java.class.path"),
|
System.getProperty("java.class.path"),
|
||||||
InheritIOEHandle.class.getName(),
|
InheritIOEHandle.class.getName(),
|
||||||
processName
|
processName
|
||||||
};
|
};
|
||||||
return cmdArray;
|
return cmdArray;
|
||||||
}
|
}
|
||||||
@ -59,19 +60,18 @@ public class InheritIOEHandle {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length > 0) {
|
APP app = (args.length > 0) ? APP.valueOf(args[0]) : APP.A;
|
||||||
APP app = APP.valueOf(args[0]);
|
switch (app) {
|
||||||
switch (app) {
|
case A:
|
||||||
|
performA();
|
||||||
|
break;
|
||||||
case B:
|
case B:
|
||||||
performB();
|
performB();
|
||||||
break;
|
break;
|
||||||
case C:
|
case C:
|
||||||
performC();
|
performC();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
performA();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void performA() {
|
private static void performA() {
|
||||||
@ -87,25 +87,40 @@ public class InheritIOEHandle {
|
|||||||
process.getOutputStream().close();
|
process.getOutputStream().close();
|
||||||
process.getErrorStream().close();
|
process.getErrorStream().close();
|
||||||
|
|
||||||
try (BufferedReader in = new BufferedReader( new InputStreamReader(
|
boolean isSignalReceived = false;
|
||||||
process.getInputStream(), "utf-8")))
|
try (BufferedReader in = new BufferedReader(new InputStreamReader(
|
||||||
|
process.getInputStream(), "utf-8")))
|
||||||
{
|
{
|
||||||
String result;
|
String result;
|
||||||
while ((result = in.readLine()) != null) {
|
while ((result = in.readLine()) != null) {
|
||||||
if (!SIGNAL.equals(result)) {
|
if (SIGNAL.equals(result)) {
|
||||||
throw new Error("Catastrophe in process B! Bad output.");
|
isSignalReceived = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Catastrophe in process B! Bad output.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!isSignalReceived) {
|
||||||
|
throw new RuntimeException("Signal from B was not received");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If JDK-7147084 is not fixed that point is unreachable.
|
// If JDK-7147084 is not fixed that point is unreachable.
|
||||||
|
System.out.println("Received signal from B, creating file StopC");
|
||||||
// write signal file
|
// write signal file
|
||||||
stopC.createNewFile();
|
boolean isFileStopC = stopC.createNewFile();
|
||||||
|
if (!isFileStopC) {
|
||||||
|
throw new RuntimeException("Signal file StopC.txt was not created. TEST or INFRA bug");
|
||||||
|
}
|
||||||
|
|
||||||
|
process.waitFor();
|
||||||
|
|
||||||
System.err.println("Read stream finished.");
|
System.err.println("Read stream finished.");
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new Error("Catastrophe in process A!", ex);
|
throw new RuntimeException("Catastrophe in process A!", ex);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
throw new RuntimeException("A was interrupted while waiting for B", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,27 +136,31 @@ public class InheritIOEHandle {
|
|||||||
process.getErrorStream().close();
|
process.getErrorStream().close();
|
||||||
|
|
||||||
System.out.println(SIGNAL);
|
System.out.println(SIGNAL);
|
||||||
|
process.waitFor();
|
||||||
|
|
||||||
// JDK-7147084 subject:
|
// JDK-7147084 subject:
|
||||||
// Process C inherits the [System.out] handle and
|
// Process C inherits the [System.out] handle and
|
||||||
// handle close in B does not finalize the streaming for A.
|
// handle close in B does not finalize the streaming for A.
|
||||||
// (handle reference count > 1).
|
// (handle reference count > 1).
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new Error("Catastrophe in process B!", ex);
|
throw new RuntimeException("Catastrophe in process B!", ex);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
throw new RuntimeException("B was interrupted while waiting for C", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void performC() {
|
private static void performC() {
|
||||||
// If JDK-7147084 is not fixed the loop is 5min long.
|
// If JDK-7147084 is not fixed the loop is 5min long.
|
||||||
for (int i = 0; i < 5*60; ++i) {
|
for (int i = 0; i < 5 * 60; ++i) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
// check for sucess
|
|
||||||
if (stopC.exists())
|
|
||||||
break;
|
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
// that is ok. Longer sleep - better effect.
|
// that is ok. Longer sleep - better effect.
|
||||||
}
|
}
|
||||||
|
// check for success
|
||||||
|
if (stopC.exists()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,21 +37,22 @@ import java.util.concurrent.CyclicBarrier;
|
|||||||
|
|
||||||
public class SiblingIOEHandle {
|
public class SiblingIOEHandle {
|
||||||
private static enum APP {
|
private static enum APP {
|
||||||
B, C;
|
A, B, C;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File stopC = new File(".\\StopCs.txt");
|
private static File stopC = new File(".\\StopCs.txt");
|
||||||
private static String SIGNAL = "B child reported.";
|
private static String SIGNAL = "B child reported.";
|
||||||
private static String JAVA_EXE = System.getProperty("java.home")
|
private static String JAVA_EXE = System.getProperty("java.home")
|
||||||
+ File.separator + "bin"
|
+ File.separator + "bin"
|
||||||
+ File.separator + "java";
|
+ File.separator + "java";
|
||||||
|
|
||||||
private static String[] getCommandArray(String processName) {
|
private static String[] getCommandArray(String processName) {
|
||||||
String[] cmdArray = {
|
String[] cmdArray = {
|
||||||
JAVA_EXE,
|
JAVA_EXE,
|
||||||
"-cp",
|
"-cp",
|
||||||
System.getProperty("java.class.path"),
|
System.getProperty("java.class.path"),
|
||||||
SiblingIOEHandle.class.getName(),
|
SiblingIOEHandle.class.getName(),
|
||||||
processName
|
processName
|
||||||
};
|
};
|
||||||
return cmdArray;
|
return cmdArray;
|
||||||
}
|
}
|
||||||
@ -61,20 +62,19 @@ public class SiblingIOEHandle {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.length > 0) {
|
APP app = (args.length > 0) ? APP.valueOf(args[0]) : APP.A;
|
||||||
APP app = APP.valueOf(args[0]);
|
switch (app) {
|
||||||
switch (app) {
|
case A:
|
||||||
|
performA(true);
|
||||||
|
performA(false);
|
||||||
|
break;
|
||||||
case B:
|
case B:
|
||||||
performB();
|
performB();
|
||||||
break;
|
break;
|
||||||
case C:
|
case C:
|
||||||
performC();
|
performC();
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
performA(true);
|
|
||||||
performA(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean procClaunched = false;
|
static boolean procClaunched = false;
|
||||||
@ -86,6 +86,7 @@ public class SiblingIOEHandle {
|
|||||||
// that was long enough
|
// that was long enough
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean waitBarrier(CyclicBarrier barrier) {
|
private static boolean waitBarrier(CyclicBarrier barrier) {
|
||||||
while (true) try {
|
while (true) try {
|
||||||
barrier.await();
|
barrier.await();
|
||||||
@ -98,6 +99,36 @@ public class SiblingIOEHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ProcessC implements Runnable {
|
||||||
|
private CyclicBarrier barrier;
|
||||||
|
private Process processC;
|
||||||
|
|
||||||
|
public ProcessC(CyclicBarrier barrier) {
|
||||||
|
this.barrier = barrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
if (waitBarrier(barrier)) {
|
||||||
|
waitAbit();
|
||||||
|
// Run process C next to B ASAP to make an attempt
|
||||||
|
// to capture the B-process IOE handles in C process.
|
||||||
|
ProcessBuilder builderC = new ProcessBuilder(
|
||||||
|
getCommandArray(APP.C.name()));
|
||||||
|
processC = builderC.start();
|
||||||
|
procClaunched = true;
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitFor() throws InterruptedException {
|
||||||
|
processC.waitFor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void performA(boolean fileOut) {
|
private static void performA(boolean fileOut) {
|
||||||
try {
|
try {
|
||||||
stopC.delete();
|
stopC.delete();
|
||||||
@ -112,26 +143,13 @@ public class SiblingIOEHandle {
|
|||||||
builderB.redirectErrorStream(true);
|
builderB.redirectErrorStream(true);
|
||||||
|
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(2);
|
final CyclicBarrier barrier = new CyclicBarrier(2);
|
||||||
Thread procCRunner = new Thread(new Runnable() {
|
//Create process C in a new thread
|
||||||
@Override public void run() {
|
ProcessC processC = new ProcessC(barrier);
|
||||||
try {
|
Thread procCRunner = new Thread(processC);
|
||||||
if (waitBarrier(barrier)) {
|
|
||||||
waitAbit();
|
|
||||||
// Run process C next to B ASAP to make an attempt
|
|
||||||
// to capture the B-process IOE handles in C process.
|
|
||||||
Runtime.getRuntime().exec(getCommandArray(APP.C.name()));
|
|
||||||
procClaunched = true;
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
procCRunner.start();
|
procCRunner.start();
|
||||||
|
|
||||||
|
|
||||||
if (!waitBarrier(barrier)) {
|
if (!waitBarrier(barrier)) {
|
||||||
throw new Error("Catastrophe in process A! Synchronization failed.");
|
throw new RuntimeException("Catastrophe in process A! Synchronization failed.");
|
||||||
}
|
}
|
||||||
// Run process B first.
|
// Run process B first.
|
||||||
Process processB = builderB.start();
|
Process processB = builderB.start();
|
||||||
@ -144,7 +162,7 @@ public class SiblingIOEHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!procClaunched) {
|
if (!procClaunched) {
|
||||||
throw new Error("Catastrophe in process A! C was not launched.");
|
throw new RuntimeException("Catastrophe in process A! C was not launched.");
|
||||||
}
|
}
|
||||||
|
|
||||||
processB.getOutputStream().close();
|
processB.getOutputStream().close();
|
||||||
@ -154,25 +172,30 @@ public class SiblingIOEHandle {
|
|||||||
try {
|
try {
|
||||||
processB.waitFor();
|
processB.waitFor();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
throw new Error("Catastrophe in process B! B hung up.");
|
throw new RuntimeException("Catastrophe in process B! B hung up.");
|
||||||
}
|
}
|
||||||
System.err.println("Trying to delete [outB.txt].");
|
System.err.println("Trying to delete [outB.txt].");
|
||||||
if (!outB.delete()) {
|
if (!outB.delete()) {
|
||||||
throw new Error("Greedy brother C deadlock! File share.");
|
throw new RuntimeException("Greedy brother C deadlock! File share.");
|
||||||
}
|
}
|
||||||
System.err.println("Succeeded in delete [outB.txt].");
|
System.err.println("Succeeded in delete [outB.txt].");
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Read stream start.");
|
System.err.println("Read stream start.");
|
||||||
try (BufferedReader in = new BufferedReader( new InputStreamReader(
|
boolean isSignalReceived = false;
|
||||||
processB.getInputStream(), "utf-8")))
|
try (BufferedReader in = new BufferedReader(new InputStreamReader(
|
||||||
{
|
processB.getInputStream(), "utf-8"))) {
|
||||||
String result;
|
String result;
|
||||||
while ((result = in.readLine()) != null) {
|
while ((result = in.readLine()) != null) {
|
||||||
if (!SIGNAL.equals(result)) {
|
if (SIGNAL.equals(result)) {
|
||||||
throw new Error("Catastrophe in process B! Bad output.");
|
isSignalReceived = true;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Catastrophe in process B! Bad output.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!isSignalReceived) {
|
||||||
|
throw new RuntimeException("Signal from B was not received");
|
||||||
|
}
|
||||||
System.err.println("Read stream finished.");
|
System.err.println("Read stream finished.");
|
||||||
}
|
}
|
||||||
// If JDK-6921885 is not fixed that point is unreachable.
|
// If JDK-6921885 is not fixed that point is unreachable.
|
||||||
@ -180,8 +203,11 @@ public class SiblingIOEHandle {
|
|||||||
|
|
||||||
// write signal file to stop C process.
|
// write signal file to stop C process.
|
||||||
stopC.createNewFile();
|
stopC.createNewFile();
|
||||||
|
processC.waitFor();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new Error("Catastrophe in process A!", ex);
|
throw new RuntimeException("Catastrophe in process A!", ex);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
throw new RuntimeException("Process A was interrupted while waiting for C", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +217,7 @@ public class SiblingIOEHandle {
|
|||||||
|
|
||||||
private static void performC() {
|
private static void performC() {
|
||||||
// If JDK-7147084 is not fixed the loop is 5min long.
|
// If JDK-7147084 is not fixed the loop is 5min long.
|
||||||
for (int i = 0; i < 5*60; ++i) {
|
for (int i = 0; i < 5 * 60; ++i) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
// check for sucess
|
// check for sucess
|
||||||
|
Loading…
x
Reference in New Issue
Block a user