From owner-freebsd-current Sun Sep 22 01:38:06 1996 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id BAA29322 for current-outgoing; Sun, 22 Sep 1996 01:38:06 -0700 (PDT) Received: from melb.werple.net.au (melb.werple.net.au [203.9.190.18]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id BAA29292 for ; Sun, 22 Sep 1996 01:38:02 -0700 (PDT) Received: (from uucp@localhost) by melb.werple.net.au (8.7.6/8.7.3/2) with UUCP id RAA25150; Sun, 22 Sep 1996 17:52:31 +1000 (EST) Received: (from jb@localhost) by freebsd3.cimlogic.com.au (8.7.5/8.7.3) id RAA15900; Sun, 22 Sep 1996 17:28:38 +1000 (EST) From: John Birrell Message-Id: <199609220728.RAA15900@freebsd3.cimlogic.com.au> Subject: Re: libc_r bug To: hsu@freefall.freebsd.org (Jeffrey Hsu) Date: Sun, 22 Sep 1996 17:28:38 +1000 (EST) Cc: jb@cimlogic.com.au, current@FreeBSD.org In-Reply-To: <199609220613.XAA28775@freefall.freebsd.org> from Jeffrey Hsu at "Sep 21, 96 11:13:07 pm" X-Mailer: ELM [version 2.4ME+ PL22 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-current@FreeBSD.org X-Loop: FreeBSD.org Precedence: bulk [ Redirected cc to -current ] > > _thread_fd_table_init() just sets up > > the table for a fd. fds 0, 1 and 2 don't have to be valid. > > Since we can't tell whether a given fd might need a call to > _thread_fd_table_init() or not, the correctness before all else > principle would argue for either pre-allocating all the fd entries > or doing it on demand by placing a call to _thread_fd_table_init() > in write() and all the other places where it might be needed. Of > these two, I prefer the second. What about you? I prefer the second too. A call to _thread_fd_table_init() in write() is only needed if the fd is nonblocking (wrt to the thread), because _thread_fd_lock() calls _thread_fd_table_init() anyway. But you can't check if the fd is nonblocking without calling _thread_fd_table_init(), so we might as well just say that the fd is always locked, even if it is nonblocking and take the same performance hit. Try the attached diff (which I haven't compiled 8-). -- John Birrell CIMlogic Pty Ltd jb@cimlogic.com.au 119 Cecil Street Ph +61 3 9690 6900 South Melbourne Vic 3205 Fax +61 3 9690 6650 Australia Mob +61 18 353 137 *** /u/freebsd/src/lib/libc_r/uthread/uthread_write.c Mon Jan 22 11:23:54 1996 --- /u/freebsd/newsrc/lib/libc_r/uthread/uthread_write.c Sun Sep 22 17:22:34 1996 *************** *** 45,56 **** int nonblock; int ret; int status; ! if (fd < 0 || fd > _thread_dtablesize || _thread_fd_table[fd] == NULL) { ! _thread_seterrno(_thread_run, EBADF); ! ret = -1; ! } else if ((nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK) == 0 && (ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) != 0) { /* Cannot lock file descriptor. */ } else { while ((ret = _thread_sys_write(fd, buf, nbytes)) < 0) { if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { _thread_kern_sig_block(&status); --- 45,54 ---- int nonblock; int ret; int status; ! if (ret = _thread_fd_lock(fd, FD_RDWR, NULL, __FILE__, __LINE__)) != 0) { /* Cannot lock file descriptor. */ } else { + nonblock = _thread_fd_table[fd]->flags & O_NONBLOCK; while ((ret = _thread_sys_write(fd, buf, nbytes)) < 0) { if (nonblock == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { _thread_kern_sig_block(&status); *************** *** 65,73 **** break; } } ! if (nonblock == 0) { ! _thread_fd_unlock(fd, FD_RDWR); ! } } return (ret); } --- 63,69 ---- break; } } ! _thread_fd_unlock(fd, FD_RDWR); } return (ret); }