Date: Mon, 11 Dec 2006 16:07:09 +0100 (CET) From: "Arne H. Juul" <arnej@pvv.ntnu.no> To: freebsd-java@FreeBSD.org Cc: freebsd-threads@freebsd.org Subject: Re: close() of active socket does not work on FreeBSD 6 Message-ID: <Pine.LNX.4.62.0612111552480.16908@decibel.pvv.ntnu.no> In-Reply-To: <Pine.LNX.4.62.0612111535280.32258@decibel.pvv.ntnu.no> References: <Pine.LNX.4.62.0612111535280.32258@decibel.pvv.ntnu.no>
next in thread | previous in thread | raw e-mail | index | archive | help
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 <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> 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; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.LNX.4.62.0612111552480.16908>