MFC:
- Fix ncp_poll() to not panic by faking up enough poll(2) state in the current thread. - Fix the rselect() routines for netncp and netsmb to return EWOULDBLOCK if the timeout is elapsed before they can block and to invoke pru_sopoll() directly.
This commit is contained in:
parent
b01e8aa321
commit
47cc69d311
@ -186,10 +186,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 so->so_proto->pr_usrreqs->pru_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 = so->so_proto->pr_usrreqs->pru_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
|
||||
@ -197,7 +215,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;
|
||||
@ -219,16 +237,18 @@ retry:
|
||||
mtx_unlock(&sellock);
|
||||
|
||||
TAILQ_INIT(&td->td_selq);
|
||||
error = ncp_poll(so, events);
|
||||
revents = so->so_proto->pr_usrreqs->pru_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);
|
||||
|
@ -95,19 +95,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 nbp->nbp_tso->so_proto->pr_usrreqs->pru_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;
|
||||
@ -130,16 +123,19 @@ retry:
|
||||
|
||||
/* XXX: Should be done when the thread is initialized. */
|
||||
TAILQ_INIT(&td->td_selq);
|
||||
error = nb_poll(nbp, events, td);
|
||||
revents = nbp->nbp_tso->so_proto->pr_usrreqs->pru_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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user