diff -r 67328babe531 -r ec908b8eb5cc jdk/test/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java --- 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 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(); + } } +