diff options
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r-- | sys/kern/uipc_syscalls.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index e3aca30..2db7778 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)uipc_syscalls.c 8.4 (Berkeley) 2/21/94 - * $Id: uipc_syscalls.c,v 1.22 1997/02/22 09:39:29 peter Exp $ + * $Id: uipc_syscalls.c,v 1.23 1997/03/23 03:36:32 bde Exp $ */ #include "opt_ktrace.h" @@ -208,20 +208,36 @@ accept1(p, uap, retval, compat) splx(s); return (error); } + + /* + * At this point we know that there is at least one connection + * ready to be accepted. Remove it from the queue prior to + * allocating the file descriptor for it since falloc() may + * block allowing another process to accept the connection + * instead. + */ + so = head->so_comp.tqh_first; + TAILQ_REMOVE(&head->so_comp, so, so_list); + head->so_qlen--; + fflag = fp->f_flag; error = falloc(p, &fp, retval); if (error) { + /* + * Probably ran out of file descriptors. Put the + * unaccepted connection back onto the queue and + * do another wakeup so some other process might + * have a chance at it. + */ + TAILQ_INSERT_HEAD(&head->so_comp, so, so_list); + head->so_qlen++; + wakeup_one(&head->so_timeo); splx(s); return (error); } - so = head->so_comp.tqh_first; - if (so == NULL) - panic("accept: nothing queued"); - TAILQ_REMOVE(&head->so_comp, so, so_list); so->so_state &= ~SS_COMP; so->so_head = NULL; - head->so_qlen--; fp->f_type = DTYPE_SOCKET; fp->f_flag = fflag; |