aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/uipc_sockbuf.c8
-rw-r--r--sys/kern/uipc_socket.c16
-rw-r--r--sys/kern/uipc_syscalls.c9
3 files changed, 24 insertions, 9 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index e1fc34106819..be4c0a250793 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -137,8 +137,12 @@ int
sblock(struct sockbuf *sb, int flags)
{
- if (flags == M_WAITOK) {
- if (sb->sb_flags & SB_NOINTR) {
+ KASSERT((flags & SBL_VALID) == flags,
+ ("sblock: flags invalid (0x%x)", flags));
+
+ if (flags & SBL_WAIT) {
+ if ((sb->sb_flags & SB_NOINTR) ||
+ (flags & SBL_NOINTR)) {
sx_xlock(&sb->sb_sx);
return (0);
}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index e2cf09b00457..9c83b04a1565 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -916,7 +916,7 @@ out:
}
#endif /*ZERO_COPY_SOCKETS*/
-#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? M_NOWAIT : M_WAITOK)
+#define SBLOCKWAIT(f) (((f) & MSG_DONTWAIT) ? 0 : SBL_WAIT)
int
sosend_dgram(struct socket *so, struct sockaddr *addr, struct uio *uio,
@@ -1884,10 +1884,16 @@ sorflush(struct socket *so)
* however, we have to initialize and destroy the mutex in the copy
* so that dom_dispose() and sbrelease() can lock t as needed.
*/
- (void) sblock(sb, M_WAITOK);
- SOCKBUF_LOCK(sb);
- sb->sb_flags |= SB_NOINTR;
- socantrcvmore_locked(so);
+
+ /*
+ * Dislodge threads currently blocked in receive and wait to acquire
+ * a lock against other simultaneous readers before clearing the
+ * socket buffer. Don't let our acquire be interrupted by a signal
+ * despite any existing socket disposition on interruptable waiting.
+ */
+ socantrcvmore(so);
+ (void) sblock(sb, SBL_WAIT | SBL_NOINTR);
+
/*
* Invalidate/clear most of the sockbuf structure, but leave selinfo
* and mutex data unchanged.
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 2821a5ea07c5..6ffcda2feb72 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1881,8 +1881,13 @@ kern_sendfile(struct thread *td, struct sendfile_args *uap,
}
}
- /* Protect against multiple writers to the socket. */
- (void) sblock(&so->so_snd, M_WAITOK);
+ /*
+ * Protect against multiple writers to the socket.
+ *
+ * XXXRW: Historically this has assumed non-interruptibility, so now
+ * we implement that, but possibly shouldn't.
+ */
+ (void)sblock(&so->so_snd, SBL_WAIT | SBL_NOINTR);
/*
* Loop through the pages of the file, starting with the requested