Date: Sun, 22 Sep 1996 17:28:38 +1000 (EST) From: John Birrell <jb@cimlogic.com.au> To: hsu@freefall.freebsd.org (Jeffrey Hsu) Cc: jb@cimlogic.com.au, current@FreeBSD.org Subject: Re: libc_r bug Message-ID: <199609220728.RAA15900@freebsd3.cimlogic.com.au> In-Reply-To: <199609220613.XAA28775@freefall.freebsd.org> from Jeffrey Hsu at "Sep 21, 96 11:13:07 pm"
next in thread | previous in thread | raw e-mail | index | archive | help
[ 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);
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199609220728.RAA15900>
