diff options
author | tanimura <tanimura@FreeBSD.org> | 2001-05-14 05:26:48 +0000 |
---|---|---|
committer | tanimura <tanimura@FreeBSD.org> | 2001-05-14 05:26:48 +0000 |
commit | 90ac553bec09bba7ec7832b74ff5390e11421b14 (patch) | |
tree | 6e6f3d78ddb96218fc7b19a7e41165b65e2c1100 /sys/netsmb/smb_trantcp.c | |
parent | ee368059840ce13cb43ccfbcfb7d4fcb8e06f76c (diff) | |
download | FreeBSD-src-90ac553bec09bba7ec7832b74ff5390e11421b14.zip FreeBSD-src-90ac553bec09bba7ec7832b74ff5390e11421b14.tar.gz |
- Convert msleep(9) in select(2) and poll(2) to cv_*wait*(9).
- Since polling should not involve sleeping, keep holding a
process lock upon scanning file descriptors.
- Hold a reference to every file descriptor prior to entering
polling loop in order to avoid lock order reversal between
lockmgr and p_mtx upon calling fdrop() in fo_poll().
(NOTE: this work has not been done for netncp and netsmb
yet because a socket itself has no reference counts.)
Reviewed by: jhb
Diffstat (limited to 'sys/netsmb/smb_trantcp.c')
-rw-r--r-- | sys/netsmb/smb_trantcp.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c index c9d0622..fea2469 100644 --- a/sys/netsmb/smb_trantcp.c +++ b/sys/netsmb/smb_trantcp.c @@ -43,6 +43,7 @@ #include <sys/poll.h> #include <sys/uio.h> #include <sys/sysctl.h> +#include <sys/condvar.h> #include <net/if.h> #include <net/route.h> @@ -100,18 +101,19 @@ static int nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events, struct proc *p) { struct timeval atv, rtv, ttv; - int s, timo, error; + int timo, error; if (tv) { atv = *tv; if (itimerfix(&atv)) { error = EINVAL; - goto done; + goto done_noproclock; } getmicrouptime(&rtv); timevaladd(&atv, &rtv); } timo = 0; + PROC_LOCK(p); retry: p->p_flag |= P_SELECT; error = nb_poll(nbp, events, p); @@ -127,16 +129,18 @@ retry: timevalsub(&ttv, &rtv); timo = tvtohz(&ttv); } - s = splhigh(); - if ((p->p_flag & P_SELECT) == 0) { - splx(s); - goto retry; - } p->p_flag &= ~P_SELECT; - error = tsleep((caddr_t)&selwait, PSOCK, "nbsel", timo); - splx(s); + if (timo > 0) + error = cv_timedwait(&selwait, &p->p_mtx, timo); + else { + cv_wait(&selwait, &p->p_mtx); + error = 0; + } + done: + PROC_UNLOCK(p); p->p_flag &= ~P_SELECT; +done_noproclock: if (error == ERESTART) return 0; return error; |