diff options
author | Jilles Tjoelker <jilles@FreeBSD.org> | 2013-04-30 15:06:30 +0000 |
---|---|---|
committer | Jilles Tjoelker <jilles@FreeBSD.org> | 2013-04-30 15:06:30 +0000 |
commit | cd31b6dd088b444c343015b21fd67c3f11dda492 (patch) | |
tree | 8df45b1b798baa202342b0a6401417cced9b4fd3 /sys | |
parent | 1c12d03f5e3c52ddd44feb2a5be1bd29ea48ab8c (diff) | |
download | src-cd31b6dd088b444c343015b21fd67c3f11dda492.tar.gz src-cd31b6dd088b444c343015b21fd67c3f11dda492.zip |
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
Notes
Notes:
svn path=/head/; revision=250102
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/uipc_socket.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index ea55e4e2411b..7986c4b1b6c8 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -2429,9 +2429,11 @@ soshutdown(struct socket *so, int how) sorflush(so); if (how != SHUT_RD) { error = (*pr->pr_usrreqs->pru_shutdown)(so); + wakeup(&so->so_timeo); CURVNET_RESTORE(); return (error); } + wakeup(&so->so_timeo); CURVNET_RESTORE(); return (0); } |