atom feed32 messages in org.freebsd.freebsd-archclose() of active socket does not wor...
FromSent OnAttachments
Kostik BelousovDec 11, 2006 9:11 am 
Arne H. JuulDec 11, 2006 2:40 pm 
David XuDec 11, 2006 4:15 pm 
Arne H. JuulDec 11, 2006 4:50 pm 
David XuDec 11, 2006 5:05 pm 
Daniel EischenDec 11, 2006 5:08 pm 
Bruce EvansDec 11, 2006 9:54 pm 
Poul-Henning KampDec 11, 2006 10:43 pm 
Daniel EischenDec 12, 2006 5:21 am 
Kostik BelousovDec 12, 2006 5:59 am 
Daniel EischenDec 12, 2006 6:24 am 
Daniel EischenDec 12, 2006 6:35 am 
Kostik BelousovDec 12, 2006 6:38 am 
Daniel EischenDec 12, 2006 12:49 pm 
David XuDec 12, 2006 3:29 pm 
Bruce EvansDec 12, 2006 7:28 pm 
Julian ElischerDec 12, 2006 11:12 pm 
Bruce EvansDec 13, 2006 3:28 am 
David XuDec 13, 2006 4:10 am 
Daniel EischenDec 13, 2006 6:23 am 
Robert WatsonDec 20, 2006 8:22 am 
Daniel EischenDec 20, 2006 10:28 am 
David XuDec 20, 2006 4:19 pm 
Julian ElischerDec 21, 2006 5:02 am 
Robert WatsonDec 21, 2006 5:46 am 
Robert WatsonDec 21, 2006 7:21 am 
Daniel EischenDec 21, 2006 9:15 am 
John-Mark GurneyDec 21, 2006 6:17 pm 
David XuDec 21, 2006 6:42 pm 
Daniel EischenDec 21, 2006 7:35 pm 
John-Mark GurneyDec 21, 2006 8:07 pm 
Daniel EischenDec 21, 2006 8:16 pm 
Subject:close() of active socket does not work on FreeBSD 6
From:Kostik Belousov (kost@gmail.com)
Date:Dec 11, 2006 9:11:10 am
List:org.freebsd.freebsd-arch

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.