提交 05fcc8ff 编写于 作者: I igerasim

8034262: Test java/lang/ProcessBuilder/CloseRace.java fails

Reviewed-by: martin, dholmes
上级 7231e628
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
public class CloseRace { public class CloseRace {
private static final String BIG_FILE = "bigfile"; private static final String BIG_FILE = "bigfile";
...@@ -43,6 +45,9 @@ public class CloseRace { ...@@ -43,6 +45,9 @@ public class CloseRace {
private static final int testDurationSeconds private static final int testDurationSeconds
= Integer.getInteger("test.duration", 600); = Integer.getInteger("test.duration", 600);
private static final CountDownLatch threadsStarted
= new CountDownLatch(2);
static boolean fdInUse(int i) { static boolean fdInUse(int i) {
return new File("/proc/self/fd/" + i).exists(); return new File("/proc/self/fd/" + i).exists();
} }
...@@ -61,6 +66,18 @@ public class CloseRace { ...@@ -61,6 +66,18 @@ public class CloseRace {
return count; return count;
} }
static void dumpAllStacks() {
System.err.println("Start of dump");
final Map<Thread, StackTraceElement[]> allStackTraces
= Thread.getAllStackTraces();
for (Thread thread : allStackTraces.keySet()) {
System.err.println("Thread " + thread.getName());
for (StackTraceElement element : allStackTraces.get(thread))
System.err.println("\t" + element);
}
System.err.println("End of dump");
}
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
if (!(new File("/proc/self/fd").isDirectory())) if (!(new File("/proc/self/fd").isDirectory()))
return; return;
...@@ -84,26 +101,41 @@ public class CloseRace { ...@@ -84,26 +101,41 @@ public class CloseRace {
for (Thread thread : threads) for (Thread thread : threads)
thread.start(); thread.start();
threadsStarted.await();
Thread.sleep(testDurationSeconds * 1000); Thread.sleep(testDurationSeconds * 1000);
for (Thread thread : threads) for (Thread thread : threads)
thread.interrupt(); thread.interrupt();
for (Thread thread : threads) for (Thread thread : threads) {
thread.join(); thread.join(10_000);
if (thread.isAlive()) {
dumpAllStacks();
throw new Error("At least one child thread ("
+ thread.getName()
+ ") failed to finish gracefully");
}
}
} }
static class OpenLoop implements Runnable { static class OpenLoop implements Runnable {
public void run() { public void run() {
threadsStarted.countDown();
while (!Thread.interrupted()) { while (!Thread.interrupted()) {
try { try {
// wait for ExecLoop to finish creating process // wait for ExecLoop to finish creating process
do {} while (count(procFDsInUse()) != 3); do {
if (Thread.interrupted())
return;
} while (count(procFDsInUse()) != 3);
List<InputStream> iss = new ArrayList<>(4); List<InputStream> iss = new ArrayList<>(4);
// eat up three "holes" (closed ends of pipe fd pairs) // eat up three "holes" (closed ends of pipe fd pairs)
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
iss.add(new FileInputStream(BIG_FILE)); iss.add(new FileInputStream(BIG_FILE));
do {} while (count(procFDsInUse()) == procFDs.length); do {
if (Thread.interrupted())
return;
} while (count(procFDsInUse()) == procFDs.length);
// hopefully this will racily occupy empty fd slot // hopefully this will racily occupy empty fd slot
iss.add(new FileInputStream(BIG_FILE)); iss.add(new FileInputStream(BIG_FILE));
Thread.sleep(1); // Widen race window Thread.sleep(1); // Widen race window
...@@ -120,11 +152,15 @@ public class CloseRace { ...@@ -120,11 +152,15 @@ public class CloseRace {
static class ExecLoop implements Runnable { static class ExecLoop implements Runnable {
public void run() { public void run() {
threadsStarted.countDown();
ProcessBuilder builder = new ProcessBuilder("/bin/true"); ProcessBuilder builder = new ProcessBuilder("/bin/true");
while (!Thread.interrupted()) { while (!Thread.interrupted()) {
try { try {
// wait for OpenLoop to finish // wait for OpenLoop to finish
do {} while (count(procFDsInUse()) > 0); do {
if (Thread.interrupted())
return;
} while (count(procFDsInUse()) > 0);
Process process = builder.start(); Process process = builder.start();
InputStream is = process.getInputStream(); InputStream is = process.getInputStream();
process.waitFor(); process.waitFor();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册