summaryrefslogtreecommitdiffstats
path: root/sys/netncp
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-08-03 15:31:52 +0000
committerjhb <jhb@FreeBSD.org>2006-08-03 15:31:52 +0000
commit0daea30185ec4572823e7ab6d4288889af965184 (patch)
tree6f9469d0d9c7f2244ecf78fde771e50720c28770 /sys/netncp
parentd0aaec359fd46d2e4ee51f1079a060a0bd9f2b84 (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys/netncp')
-rw-r--r--sys/netncp/ncp_sock.c34
1 files changed, 27 insertions, 7 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);
OpenPOWER on IntegriCloud