diff options
author | Robert Watson <rwatson@FreeBSD.org> | 2004-06-17 22:48:11 +0000 |
---|---|---|
committer | Robert Watson <rwatson@FreeBSD.org> | 2004-06-17 22:48:11 +0000 |
commit | 9535efc00de36129762534223a2f5782cc5fe472 (patch) | |
tree | 743d1903dca8bb885b1a5cafc69c5ea6ff190d62 /sys/kern/sys_socket.c | |
parent | b2c082c98b71834582bad5480fdea168a89691c5 (diff) |
Notes
Diffstat (limited to 'sys/kern/sys_socket.c')
-rw-r--r-- | sys/kern/sys_socket.c | 20 |
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); |