From owner-freebsd-arch@FreeBSD.ORG Mon Dec 11 17:11:25 2006 Return-Path: X-Original-To: freebsd-arch@freebsd.org Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C578A16A415; Mon, 11 Dec 2006 17:11:25 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from fw.zoral.com.ua (fw.zoral.com.ua [213.186.206.134]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4BAE743C9E; Mon, 11 Dec 2006 17:10:06 +0000 (GMT) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by fw.zoral.com.ua (8.13.4/8.13.4) with ESMTP id kBBHBGA1063307 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 11 Dec 2006 19:11:16 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.13.8/8.13.8) with ESMTP id kBBHBGqu020278; Mon, 11 Dec 2006 19:11:16 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.13.8/8.13.8/Submit) id kBBHBFH3020277; Mon, 11 Dec 2006 19:11:15 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Mon, 11 Dec 2006 19:11:15 +0200 From: Kostik Belousov To: "Arne H. Juul" Message-ID: <20061211171115.GD311@deviant.kiev.zoral.com.ua> References: Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="7qSK/uQB79J36Y4o" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.2i X-Virus-Scanned: ClamAV version 0.88.4, clamav-milter version 0.88.4 on fw.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=1.4 required=5.0 tests=SPF_NEUTRAL, UNPARSEABLE_RELAY autolearn=no version=3.1.4 X-Spam-Level: * X-Spam-Checker-Version: SpamAssassin 3.1.4 (2006-07-25) on fw.zoral.com.ua Cc: freebsd-arch@freebsd.org, freebsd-java@freebsd.org Subject: Re: close() of active socket does not work on FreeBSD 6 X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Dec 2006 17:11:26 -0000 --7qSK/uQB79J36Y4o Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable 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=20 > reopen the close()'d filedescriptor, making it point to a filedescriptor= =20 > that's pre-connected to a closed socket. >=20 > 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? >=20 > 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 >=20 >=20 > #include > #include > #include > #include > #include >=20 > int p[2]; >=20 > void *run(void *arg) { > ssize_t res; > char tmp[128]; > fprintf(stderr, "reading...\n"); > res =3D read(p[0], tmp, sizeof(tmp)); > fprintf(stderr, "read result: %d\n", (int)res); > if (res < 0) { > perror("read"); > } > return arg; > } >=20 > int main(int argc, char **argv) { > pthread_t t; > int d =3D open("/dev/null", O_RDONLY); > if (pipe(p) !=3D 0) { > perror("pipe"); > return 1; > } > if (pthread_create(&t, NULL, run, NULL) !=3D 0) { > perror("thread create"); > return 1; > } > sleep(1); > d =3D 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) !=3D 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. --7qSK/uQB79J36Y4o Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (FreeBSD) iD8DBQFFfZEzC3+MBN1Mb4gRAqKBAJ0e2xoeobSLeRZjJQbFUs5/uXX3ywCgqkJM ZoWAOIyyznh7U1KYx8vpB8s= =CgYu -----END PGP SIGNATURE----- --7qSK/uQB79J36Y4o--