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/netsmb/smb_trantcp.c | |
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/netsmb/smb_trantcp.c')
-rw-r--r-- | sys/netsmb/smb_trantcp.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c index fea2469..3d6b082 100644 --- a/sys/netsmb/smb_trantcp.c +++ b/sys/netsmb/smb_trantcp.c @@ -114,17 +114,31 @@ nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events, struct proc *p) } timo = 0; PROC_LOCK(p); -retry: p->p_flag |= P_SELECT; + PROC_UNLOCK(p); error = nb_poll(nbp, events, p); + 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 = nb_poll(nbp, events, p); + PROC_LOCK(p); + } goto done; + } ttv = atv; timevalsub(&ttv, &rtv); timo = tvtohz(&ttv); |