--- a/jdk/test/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java Wed Dec 07 17:08:21 2016 -0800
+++ b/jdk/test/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java Wed Dec 07 17:15:03 2016 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,21 +22,64 @@
*/
/*
- * Test run from script, AcceptCauseFileDescriptorLeak.sh
* author Edward Wang
+ *
+ * @test
+ * @bug 6368984
+ * @summary Configuring unconnected Socket before passing to implAccept
+ * can cause fd leak
+ * @requires (os.family != "windows")
+ * @library /test/lib
+ * @build jdk.test.lib.JDKToolFinder
+ * jdk.test.lib.process.OutputAnalyzer
+ * AcceptCauseFileDescriptorLeak
+ * @run main/othervm AcceptCauseFileDescriptorLeak root
*/
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
+import java.util.List;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.OutputAnalyzer;
public class AcceptCauseFileDescriptorLeak {
private static final int REPS = 2048;
+ private static final int THRESHOLD = 1024;
public static void main(String[] args) throws Exception {
+ if (args.length != 0) {
+ OutputAnalyzer analyzer = execCmd("ulimit -n -H");
+ String output = analyzer.getOutput();
+ if (output == null || output.length() == 0) {
+ throw new RuntimeException("\"ulimit -n -H\" output nothing"
+ + " and its exit code is " + analyzer.getExitValue());
+ } else {
+ output = output.trim();
+ // Set max open file descriptors to 1024
+ // if it is unlimited or greater than 1024,
+ // otherwise just do test directly
+ if ("unlimited".equals(output)
+ || Integer.valueOf(output) > THRESHOLD) {
+ analyzer = execCmd("ulimit -n " + THRESHOLD + "; "
+ + composeJavaTestStr());
+ System.out.println("Output: ["
+ + analyzer.getOutput() + "]");
+ int rc = analyzer.getExitValue();
+ if (rc != 0) {
+ throw new RuntimeException(
+ "Unexpected exit code: " + rc);
+ }
+ return;
+ }
+ }
+ }
+
final ServerSocket ss = new ServerSocket(0) {
public Socket accept() throws IOException {
- Socket s = new Socket() { };
+ Socket s = new Socket() {
+ };
s.setSoTimeout(10000);
implAccept(s);
return s;
@@ -54,10 +97,33 @@
}
});
t.start();
- for (int i = 0; i < REPS; i++) {
- ss.accept().close();
+ try {
+ for (int i = 0; i < REPS; i++) {
+ ss.accept().close();
+ }
+ } finally {
+ ss.close();
}
- ss.close();
t.join();
}
+
+ /**
+ * Execute command with shell
+ *
+ * @param command
+ * @return OutputAnalyzer
+ * @throws IOException
+ */
+ static OutputAnalyzer execCmd(String command) throws IOException {
+ List<String> cmd = List.of("sh", "-c", command);
+ System.out.println("Executing: " + cmd);
+ ProcessBuilder pb = new ProcessBuilder(cmd);
+ return new OutputAnalyzer(pb.start());
+ }
+
+ static String composeJavaTestStr() {
+ return JDKToolFinder.getTestJDKTool("java") + " "
+ + AcceptCauseFileDescriptorLeak.class.getName();
+ }
}
+