From owner-freebsd-java@FreeBSD.ORG Mon Dec 11 15:07:10 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 DBFE516A403; Mon, 11 Dec 2006 15:07:10 +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 382E243CAC; Mon, 11 Dec 2006 15:05:53 +0000 (GMT) (envelope-from arnej@pvv.ntnu.no) Received: from arnej by decibel.pvv.ntnu.no with local (Exim 4.60) (envelope-from ) id 1GtmkH-00080J-6z; Mon, 11 Dec 2006 16:07:09 +0100 Date: Mon, 11 Dec 2006 16:07:09 +0100 (CET) From: "Arne H. Juul" To: freebsd-java@FreeBSD.org In-Reply-To: Message-ID: References: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-threads@freebsd.org Subject: Re: 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 15:07:11 -0000 On Mon, 11 Dec 2006, Arne H. Juul wrote: > 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. Looking at the Java VM source code it does some tricks with dup2() to reopen the close()'d filedescriptor, making it point to a filedescriptor that's pre-connected to a closed socket. A small C program that duplicates this (using pipes to make it a bit simpler) follows. I'm not sure if any standards demand that this works like it used to on FreeBSD 4 / libc_r, but since Java uses it it would be really nice if this could be made to work in FreeBSD 6 (libthr and libpthread). Or maybe somebody has another suggestions on how to implement the Java close() semantics? Anyway, the following C program works as intended on FreeBSD 4, hangs on FreeBSD 6 (amd64), compiled with: cc -Wall -pthread read_dup2.c -o read_dup2 #include #include #include #include #include int p[2]; void *run(void *arg) { ssize_t res; char tmp[128]; fprintf(stderr, "reading...\n"); res = read(p[0], tmp, sizeof(tmp)); fprintf(stderr, "read result: %d\n", (int)res); if (res < 0) { perror("read"); } return arg; } int main(int argc, char **argv) { pthread_t t; int d = open("/dev/null", O_RDONLY); if (pipe(p) != 0) { perror("pipe"); return 1; } if (pthread_create(&t, NULL, run, NULL) != 0) { perror("thread create"); return 1; } sleep(1); d = open("/dev/null", O_RDONLY); if (d < 0) { perror("open dev null"); exit(1); } if (dup2(d, p[0]) < 0) { perror("dup2"); exit(1); } if (pthread_join(t, NULL) != 0) { perror("thread join"); exit(1); } return 0; }