From owner-freebsd-java@FreeBSD.ORG Mon Dec 11 22:40:41 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 E163A16A4A0; Mon, 11 Dec 2006 22:40:41 +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 73FF144040; Mon, 11 Dec 2006 22:33:22 +0000 (GMT) (envelope-from arnej@pvv.ntnu.no) Received: from arnej by decibel.pvv.ntnu.no with local (Exim 4.60) (envelope-from ) id 1GttjM-0003Kw-2u; Mon, 11 Dec 2006 23:34:40 +0100 Date: Mon, 11 Dec 2006 23:34:40 +0100 (CET) From: "Arne H. Juul" To: Kostik Belousov In-Reply-To: <20061211171115.GD311@deviant.kiev.zoral.com.ua> Message-ID: References: <20061211171115.GD311@deviant.kiev.zoral.com.ua> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-arch@freebsd.org, freebsd-java@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 22:40:42 -0000 On Mon, 11 Dec 2006, Kostik Belousov wrote: > On Mon, Dec 11, 2006 at 04:07:09PM +0100, 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? > > 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. The best authority I've found says that the standards are silent (so the current FreeBSD 6 behaviour is allowed), I'm asking whether it is best practice and why it's changed since FreeBSD 4. > I think that JVM is more appropriate place for fix, but others may have > different view point. If it was just the JVM I would agree, but any threaded program that uses blocking I/O in some threads will probably need the same kind of handling at some point. And if you think about what that handling looks like, it's not exactly pretty: * when calling any potentially blocking system call (read/readv, write/writev, recv/recvfrom/recvmsg, send/sendto/sendmsg, accept, connect, poll, select, maybe others that I didn't think of) the application must: ** take a mutex ** remember in some structure (linked list or similar) keyed off the file descriptor that "this thread will now do blocking I/O" ** release the mutex ** perform the actual operation ** take the mutex again ** check if the operation was interrupted in a special way, if so return with EBADF ** release the mutex * instead of calling close() and dup2() the application must: ** take the mutex ** for each thread in the FD-associated structure, interrupt it in some special way (I'm guessing that setting a special flag and then sending SIGIO should work). ** actually do the close() / dup2() ** release the mutex This is exactly the sort of issue that should be solved by the thread library / kernel threads implementation and not in every threaded application that needs it, in my view. - Arne H. J.