From owner-freebsd-java@FreeBSD.ORG Mon Dec 11 14:46:14 2006 Return-Path: X-Original-To: freebsd-java@FreeBSD.org Delivered-To: freebsd-java@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9983216A407 for ; Mon, 11 Dec 2006 14:46:14 +0000 (UTC) (envelope-from arnej@pvv.ntnu.no) Received: from decibel.pvv.ntnu.no (decibel.pvv.ntnu.no [129.241.210.179]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2261343CBA for ; Mon, 11 Dec 2006 14:44:56 +0000 (GMT) (envelope-from arnej@pvv.ntnu.no) Received: from arnej by decibel.pvv.ntnu.no with local (Exim 4.60) (envelope-from ) id 1GtmQ0-0002pG-EW for freebsd-java@FreeBSD.org; Mon, 11 Dec 2006 15:46:12 +0100 Date: Mon, 11 Dec 2006 15:46:12 +0100 (CET) From: "Arne H. Juul" To: freebsd-java@FreeBSD.org Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: Subject: close() of active socket does not work on FreeBSD 6 X-BeenThere: freebsd-java@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting Java to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Dec 2006 14:46:14 -0000 I've had problems with some tests hanging on FreeBSD 6/amd64. This happens both with diablo-1.5.0_07-b01 and the java/jdk15 compiled from ports. After much digging we've determined that the root cause is that the guarantee in the socket.close() API, see the documentation at http://java.sun.com/j2se/1.5.0/docs/api/java/net/Socket.html#close() isn't fulfulled - the thread blocked in I/O on the socket doesn't wake up. Here's a pretty small test program that demonstrates the problem (given that you're running sshd on port 22, if not change the port number to something that the program can connect to). Is this a known problem? Does it happen for everybody on FreeBSD 6? import java.io.*; import java.net.*; import java.util.*; import java.util.logging.*; public class FooConn extends Thread { private boolean alive; public final int port; private Socket socket = null; public FooConn(int port) { super("FooConn:" + port); this.port = port; this.alive = true; } private void connect() { while (socket == null) { try { socket = new Socket("localhost", port); } catch(IOException e) { System.err.println("Connect failed: " + e); try { Thread.sleep(1000); } catch(InterruptedException ie) {} } } } public void disconnect() throws IOException, InterruptedException { alive = false; System.out.println("closing socket"); socket.close(); System.out.println("calling join"); join(); } public void run() { while (alive) { if (socket == null) { System.out.println("socket null, connect"); connect(); } try { int b = socket.getInputStream().read(); System.out.println("got byte "+ b); } catch (IOException e) { System.out.println("IOException, set socket to null"); socket = null; //triggers reconnect } catch (RuntimeException e) { System.err.println("RuntimeException "+e); return; } } } public static void main(String[] args) throws IOException { try { FooConn conn = new FooConn(22); conn.start(); Thread.sleep(1000); conn.disconnect(); } catch(InterruptedException ie) {} } }