diff options
author | tanimura <tanimura@FreeBSD.org> | 2001-05-15 10:19:57 +0000 |
---|---|---|
committer | tanimura <tanimura@FreeBSD.org> | 2001-05-15 10:19:57 +0000 |
commit | ac163f80253b962c608a2b093b66d7dbad78e43c (patch) | |
tree | ed154ff9bc31f68403ed7c49bcd0d3515131934d /sys/netncp | |
parent | 6125cb47e354f8e71ec9dc19c0688d6c7b46a588 (diff) | |
download | FreeBSD-src-ac163f80253b962c608a2b093b66d7dbad78e43c.zip FreeBSD-src-ac163f80253b962c608a2b093b66d7dbad78e43c.tar.gz |
Back out scanning file descriptors with holding a process lock.
selrecord() requires allproc sx in pfind(), resulting in lock order
reversal between allproc and a process lock.
Diffstat (limited to 'sys/netncp')
-rw-r--r-- | sys/netncp/ncp_sock.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/netncp/ncp_sock.c b/sys/netncp/ncp_sock.c index 063d007..2033441 100644 --- a/sys/netncp/ncp_sock.c +++ b/sys/netncp/ncp_sock.c @@ -202,17 +202,31 @@ ncp_sock_rselect(struct socket *so,struct proc *p, struct timeval *tv, int event } timo = 0; PROC_LOCK(p); -retry: p->p_flag |= P_SELECT; + PROC_UNLOCK(p); error = ncp_poll(so, events); + PROC_LOCK(p); if (error) { error = 0; goto done; } if (tv) { getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) + if (timevalcmp(&rtv, &atv, >=)) { + /* + * An event of our interest may occur during locking a process. + * In order to avoid missing the event that occured during locking + * the process, test P_SELECT and rescan file descriptors if + * necessary. + */ + if ((p->p_flag & P_SELECT) == 0) { + p->p_flag |= P_SELECT; + PROC_UNLOCK(p); + error = ncp_poll(so, events); + PROC_LOCK(p); + } goto done; + } ttv=atv; timevalsub(&ttv, &rtv); timo = tvtohz(&ttv); |