Re: close() of active socket does not work on FreeBSD 6



On Mon, Dec 11, 2006 at 04:07:09PM +0100, Arne H. Juul wrote:
On Mon, 11 Dec 2006, Arne H. Juul wrote:
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;
}

I think that -arch@ is proper ML to discuss the issue.

Your test example hangs becase read() takes one more hold count on the
file descriptor operated upon. As result, when calling close, f_count
of the rpipe (aka p[0]) is 2, close() decrements it, f_count becomes
1. Since f_count > 0, fdrop_locked simply returns instead of calling
fo_close (see kern_descrip.c).

I cannot find the statement in SUSv3 that would require interruption of
the read() upon close() from another thread; this looks like undefined
behaviour from the standard point of view.

I think that JVM is more appropriate place for fix, but others may have
different view point.

Attachment: pgpZQhf6IgAcM.pgp
Description: PGP signature



Relevant Pages

  • Re: close() of active socket does not work on FreeBSD 6
    ... reopen the close'd filedescriptor, making it point to a filedescriptor ... would be really nice if this could be made to work in FreeBSD 6 (libthr ... fdrop_locked simply returns instead of calling ... ** release the mutex ...
    (freebsd-arch)
  • Re: netbeans 6.0.1 not run
    ... I'm using zsh so I set JAVA_HOME and PATH of java into in my .zshrc. ... Then I insralled netbeans from ports, ... Installation went fine. ... graphical java application on FreeBSD 7 using the diablo port. ...
    (freebsd-questions)
  • Re: JAVA for FreeBSD
    ... >> Because they want that an officially endorsed Java virtual machine be ... >> able to run any java programs exactly the same as on other platforms. ... >> even now the most modern FreeBSD thread library is able to run perfectly ... JDK for your linux-distribution that wasn't included on the CD. ...
    (comp.unix.bsd.freebsd.misc)
  • Re: where exactly can I get a copy of libdl.so.2 for FreeBSD-5.4 ?
    ... because no such FreeBSD library exists. ... I imagine you'll be able to get them if you check the docs on enabling linux compat. ... Linux java plugin. ... linux mozilla binary with the linux java plugin, ...
    (comp.unix.bsd.freebsd.misc)
  • Re: Java5 and FreeBSD
    ... I made my way to Sun's java page, and then to the newest Java2 ... Yet no FreeBSD Java? ... The linux one will probably work ... > Server Platform Edition 8 is available for the following platforms: ...
    (freebsd-questions)