JDK-6368984 : configuring unconnected Socket before passing to implAccept can cause fd leak
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2006-01-05
  • Updated: 2011-03-07
  • Resolved: 2011-03-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u2Fixed 7 b03Fixed
Description
See the following thread on the RMI-USERS mailing list:
	http://archives.java.sun.com/cgi-bin/wa?A2=ind0601&L=rmi-users&P=265

It seems that certain uses of an unconnected Socket before passing it to ServerSocket.implAccept can cause a file descriptor leak.  While the fix seems to be to reorder the impl-creating operations to after the implAccept invocation, it seems like a possible bug (or at least a documentation issue) that this leak can happen silently (until all file descriptors are exhausted).  (Also, the case with setSoTimeout worked with 1.3, for what that's worth.)  Compare the behavior of the following example between 1.3 and later:

import java.io.*;
import java.net.*;

public class AcceptDescriptorLeak {
    private static final int REPS = 10000;
    public static void main(String[] args) throws Exception {
	final ServerSocket ss = new ServerSocket(0) {
	    public Socket accept() throws IOException {
		Socket s = new Socket() { };
		s.setSoTimeout(10000);
		implAccept(s);
		return s;
	    }
	};
	Thread t = new Thread(new Runnable() {
	    public void run() {
		try {
		    for (int i = 0; i < REPS; i++) {
			(new Socket("localhost", ss.getLocalPort())).close();
		    }
		} catch (IOException e) {
		    e.printStackTrace();
		}
	    }
	});
	t.setDaemon(true);
	t.start();
	for (int i = 0; i < REPS; i++) {
	    ss.accept().close();
	}
	ss.close();
    }
}

Comments
EVALUATION There's a fd leak, indeed. Will fix.
30-08-2006