summaryrefslogtreecommitdiff
path: root/sys/kern/sys_socket.c
diff options
context:
space:
mode:
authorRobert Watson <rwatson@FreeBSD.org>2004-06-17 22:48:11 +0000
committerRobert Watson <rwatson@FreeBSD.org>2004-06-17 22:48:11 +0000
commit9535efc00de36129762534223a2f5782cc5fe472 (patch)
tree743d1903dca8bb885b1a5cafc69c5ea6ff190d62 /sys/kern/sys_socket.c
parentb2c082c98b71834582bad5480fdea168a89691c5 (diff)
Notes
Diffstat (limited to 'sys/kern/sys_socket.c')
-rw-r--r--sys/kern/sys_socket.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index a580b43c9ae2a..986edf7ed5b79 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -131,21 +131,41 @@ soo_ioctl(fp, cmd, data, active_cred, td)
switch (cmd) {
case FIONBIO:
+ SOCK_LOCK(so);
if (*(int *)data)
so->so_state |= SS_NBIO;
else
so->so_state &= ~SS_NBIO;
+ SOCK_UNLOCK(so);
return (0);
case FIOASYNC:
+ /*
+ * XXXRW: This code separately acquires SOCK_LOCK(so)
+ * and SOCKBUF_LOCK(&so->so_rcv) even though they are
+ * the same mutex to avoid introducing the assumption
+ * that they are the same.
+ */
if (*(int *)data) {
+ SOCK_LOCK(so);
so->so_state |= SS_ASYNC;
+ SOCK_UNLOCK(so);
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags |= SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags |= SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_snd);
} else {
+ SOCK_LOCK(so);
so->so_state &= ~SS_ASYNC;
+ SOCK_UNLOCK(so);
+ SOCKBUF_LOCK(&so->so_rcv);
so->so_rcv.sb_flags &= ~SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ SOCKBUF_LOCK(&so->so_snd);
so->so_snd.sb_flags &= ~SB_ASYNC;
+ SOCKBUF_UNLOCK(&so->so_snd);
}
return (0);