diff options
author | jhb <jhb@FreeBSD.org> | 2006-08-03 15:31:52 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2006-08-03 15:31:52 +0000 |
commit | 0daea30185ec4572823e7ab6d4288889af965184 (patch) | |
tree | 6f9469d0d9c7f2244ecf78fde771e50720c28770 | |
parent | d0aaec359fd46d2e4ee51f1079a060a0bd9f2b84 (diff) | |
download | FreeBSD-src-0daea30185ec4572823e7ab6d4288889af965184.zip FreeBSD-src-0daea30185ec4572823e7ab6d4288889af965184.tar.gz |
- Fix ncp_poll() to not panic if the socket doesn't have any pending data.
We have to adjust curthread's state enough so that it appears to be
in a poll(2) or select(2) call so that selrecord() will work and then
teardown that state after calling sopoll().
- Fix some minor nits in nearby ncp_sock_rselect() and in the identical
nbssn_rselect() function in the netsmb code:
- Don't call nb_poll()/ncp_poll() now that ncp_poll() already fakes up
poll(2) state since the rselect() functions already do that. Just
invoke sopoll() directly.
- To make things slightly more intuitive, store the results of sopoll()
in a new 'revents' variable rather than 'error' since that's what
sopoll() actually returns.
- If the requested timeout time has been exceeded by the time we get
ready to block, then return EWOULDBLOCK rather than 0 to signal a
timeout as this is what the calling code expects.
Tested by: Eric Christeson <eric.j.christeson AT gmail> (1)
MFC after: 1 week
-rw-r--r-- | sys/netncp/ncp_sock.c | 34 | ||||
-rw-r--r-- | sys/netsmb/smb_trantcp.c | 16 |
2 files changed, 33 insertions, 17 deletions
diff --git a/sys/netncp/ncp_sock.c b/sys/netncp/ncp_sock.c index a51ead2..1e4fd9a 100644 --- a/sys/netncp/ncp_sock.c +++ b/sys/netncp/ncp_sock.c @@ -185,10 +185,28 @@ ncp_sock_send(struct socket *so, struct mbuf *top, struct ncp_rq *rqp) int ncp_poll(struct socket *so, int events) { - struct thread *td = curthread; - struct ucred *cred = NULL; + struct thread *td = curthread; + int revents; - return (sopoll(so, events, cred, td)); + /* Fake up enough state to look like we are in poll(2). */ + mtx_lock(&sellock); + mtx_lock_spin(&sched_lock); + td->td_flags |= TDF_SELECT; + mtx_unlock_spin(&sched_lock); + mtx_unlock(&sellock); + TAILQ_INIT(&td->td_selq); + + revents = sopoll(so, events, NULL, td); + + /* Tear down the fake poll(2) state. */ + mtx_lock(&sellock); + clear_selinfo_list(td); + mtx_lock_spin(&sched_lock); + td->td_flags &= ~TDF_SELECT; + mtx_unlock_spin(&sched_lock); + mtx_unlock(&sellock); + + return (revents); } int @@ -196,7 +214,7 @@ ncp_sock_rselect(struct socket *so, struct thread *td, struct timeval *tv, int events) { struct timeval atv, rtv, ttv; - int ncoll, timo, error = 0; + int ncoll, timo, error, revents; if (tv) { atv = *tv; @@ -218,16 +236,18 @@ retry: mtx_unlock(&sellock); TAILQ_INIT(&td->td_selq); - error = ncp_poll(so, events); + revents = sopoll(so, events, NULL, td); mtx_lock(&sellock); - if (error) { + if (revents) { error = 0; goto done; } if (tv) { getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) + if (timevalcmp(&rtv, &atv, >=)) { + error = EWOULDBLOCK; goto done; + } ttv = atv; timevalsub(&ttv, &rtv); timo = tvtohz(&ttv); diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c index 4c273cd..5db6b7e 100644 --- a/sys/netsmb/smb_trantcp.c +++ b/sys/netsmb/smb_trantcp.c @@ -94,18 +94,12 @@ nb_setsockopt_int(struct socket *so, int level, int name, int val) return sosetopt(so, &sopt); } -static __inline int -nb_poll(struct nbpcb *nbp, int events, struct thread *td) -{ - return sopoll(nbp->nbp_tso, events, NULL, td); -} - static int nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events, struct thread *td) { struct timeval atv, rtv, ttv; - int ncoll, timo, error; + int ncoll, timo, error, revents; if (tv) { atv = *tv; @@ -128,16 +122,18 @@ retry: /* XXX: Should be done when the thread is initialized. */ TAILQ_INIT(&td->td_selq); - error = nb_poll(nbp, events, td); + revents = sopoll(nbp->nbp_tso, events, NULL, td); mtx_lock(&sellock); - if (error) { + if (revents) { error = 0; goto done; } if (tv) { getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) + if (timevalcmp(&rtv, &atv, >=)) { + error = EWOULDBLOCK; goto done; + } ttv = atv; timevalsub(&ttv, &rtv); timo = tvtohz(&ttv); |