socket: Make shutdown() wake up a blocked accept().

A blocking accept (and some other operations) waits on &so->so_timeo. Once
it wakes up, it will detect the SBS_CANTRCVMORE bit.

The error from accept() is [ECONNABORTED] which is not the nicest one -- the
thread calling accept() needs to know out-of-band what is happening.

A spurious wakeup on so->so_timeo appears harmless (sleep retried) except
when lingering on close (SO_LINGER, and in that case there is no descriptor
to call shutdown() on) so this should be fairly safe.

A shutdown() already woke up a blocked accept() for TCP sockets, but not for
Unix domain sockets. This fix is generic for all domains.

This patch was sent to -hackers@ and -net@ on April 5.

MFC after:	2 weeks
This commit is contained in:
Jilles Tjoelker 2013-04-30 15:06:30 +00:00
parent 1c12d03f5e
commit cd31b6dd08

View File

@ -2429,9 +2429,11 @@ soshutdown(struct socket *so, int how)
sorflush(so); sorflush(so);
if (how != SHUT_RD) { if (how != SHUT_RD) {
error = (*pr->pr_usrreqs->pru_shutdown)(so); error = (*pr->pr_usrreqs->pru_shutdown)(so);
wakeup(&so->so_timeo);
CURVNET_RESTORE(); CURVNET_RESTORE();
return (error); return (error);
} }
wakeup(&so->so_timeo);
CURVNET_RESTORE(); CURVNET_RESTORE();
return (0); return (0);
} }