Tue Dec 20 23:56:29 2011 UTC ()
- Eliminate so_nbio and turn it into a bit SS_NBIO in so_state.
- Introduce MSG_NBIO so that we can turn non blocking i/o on a per call basis
- Use MSG_NBIO to fix the XXX: multi-threaded issues on the fifo sockets.
- Don't set SO_CANTRCVMORE, if we were interrupted (perhaps do it for all
  errors?).


(christos)
diff -r1.110 -r1.111 src/sys/compat/linux/common/linux_socket.c
diff -r1.28 -r1.29 src/sys/dev/kttcp.c
diff -r1.64 -r1.65 src/sys/kern/sys_socket.c
diff -r1.205 -r1.206 src/sys/kern/uipc_socket.c
diff -r1.109 -r1.110 src/sys/kern/uipc_socket2.c
diff -r1.148 -r1.149 src/sys/kern/uipc_syscalls.c
diff -r1.70 -r1.71 src/sys/miscfs/fifofs/fifo_vnops.c
diff -r1.40 -r1.41 src/sys/netiso/tp_usrreq.c
diff -r1.100 -r1.101 src/sys/sys/socket.h
diff -r1.126 -r1.127 src/sys/sys/socketvar.h

cvs diff -r1.110 -r1.111 src/sys/compat/linux/common/linux_socket.c (expand / switch to context diff)
--- src/sys/compat/linux/common/linux_socket.c 2011/07/17 23:59:54 1.110
+++ src/sys/compat/linux/common/linux_socket.c 2011/12/20 23:56:28 1.111
@@ -1,4 +1,4 @@
-/*	$NetBSD: linux_socket.c,v 1.110 2011/07/17 23:59:54 christos Exp $	*/
+/*	$NetBSD: linux_socket.c,v 1.111 2011/12/20 23:56:28 christos Exp $	*/
 
 /*-
  * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.110 2011/07/17 23:59:54 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.111 2011/12/20 23:56:28 christos Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -1376,7 +1376,7 @@
 
 	if (error == EISCONN) {
 		struct socket *so;
-		int state, prflags, nbio;
+		int state, prflags;
 
 		/* fd_getsock() will use the descriptor for us */
 	    	if (fd_getsock(SCARG(uap, s), &so) != 0)
@@ -1384,7 +1384,6 @@
 
 		solock(so);
 		state = so->so_state;
-		nbio = so->so_nbio;
 		prflags = so->so_proto->pr_flags;
 		sounlock(so);
 		fd_putfile(SCARG(uap, s));
@@ -1393,7 +1392,8 @@
 		 * non-blocking connect; however we don't have
 		 * a convenient place to keep that state..
 		 */
-		if (nbio && (state & SS_ISCONNECTED) &&
+		if ((state & (SS_ISCONNECTED|SS_NBIO)) ==
+		    (SS_ISCONNECTED|SS_NBIO) &&
 		    (prflags & PR_CONNREQUIRED))
 			return 0;
 	}

cvs diff -r1.28 -r1.29 src/sys/dev/kttcp.c (expand / switch to context diff)
--- src/sys/dev/kttcp.c 2008/04/24 11:38:36 1.28
+++ src/sys/dev/kttcp.c 2011/12/20 23:56:28 1.29
@@ -1,4 +1,4 @@
-/*	$NetBSD: kttcp.c,v 1.28 2008/04/24 11:38:36 ad Exp $	*/
+/*	$NetBSD: kttcp.c,v 1.29 2011/12/20 23:56:28 christos Exp $	*/
 
 /*
  * Copyright (c) 2002 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.28 2008/04/24 11:38:36 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.29 2011/12/20 23:56:28 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -237,7 +237,7 @@
 		if ((atomic && resid > so->so_snd.sb_hiwat))
 			snderr(EMSGSIZE);
 		if (space < resid && (atomic || space < so->so_snd.sb_lowat)) {
-			if (so->so_nbio)
+			if (so->so_state & SS_NBIO)
 				snderr(EWOULDBLOCK);
 			SBLASTRECORDCHK(&so->so_rcv,
 			    "kttcp_soreceive sbwait 1");
@@ -427,7 +427,7 @@
 		}
 		if (resid == 0)
 			goto release;
-		if (so->so_nbio || (flags & MSG_DONTWAIT)) {
+		if ((so->so_so_state & SS_NBIO) || (flags & MSG_DONTWAIT|MSG_NBIO)) {
 			error = EWOULDBLOCK;
 			goto release;
 		}

cvs diff -r1.64 -r1.65 src/sys/kern/sys_socket.c (expand / switch to context diff)
--- src/sys/kern/sys_socket.c 2011/06/30 22:38:50 1.64
+++ src/sys/kern/sys_socket.c 2011/12/20 23:56:28 1.65
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_socket.c,v 1.64 2011/06/30 22:38:50 dyoung Exp $	*/
+/*	$NetBSD: sys_socket.c,v 1.65 2011/12/20 23:56:28 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.64 2011/06/30 22:38:50 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.65 2011/12/20 23:56:28 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -127,8 +127,12 @@
 	switch (cmd) {
 
 	case FIONBIO:
-		/* No reason to lock and this call is made very often. */
-		so->so_nbio = *(int *)data;
+		solock(so);
+		if (*(int *)data)
+			so->so_state |= SS_NBIO;
+		else 
+			so->so_state &= ~SS_NBIO; 
+		sounlock(so);
 		break;
 
 	case FIOASYNC:

cvs diff -r1.205 -r1.206 src/sys/kern/uipc_socket.c (expand / switch to context diff)
--- src/sys/kern/uipc_socket.c 2011/07/02 17:53:50 1.205
+++ src/sys/kern/uipc_socket.c 2011/12/20 23:56:28 1.206
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket.c,v 1.205 2011/07/02 17:53:50 bouyer Exp $	*/
+/*	$NetBSD: uipc_socket.c,v 1.206 2011/12/20 23:56:28 christos Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.205 2011/07/02 17:53:50 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.206 2011/12/20 23:56:28 christos Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_sock_counters.h"
@@ -741,7 +741,8 @@
 				goto drop;
 		}
 		if (so->so_options & SO_LINGER) {
-			if ((so->so_state & SS_ISDISCONNECTING) && so->so_nbio)
+			if ((so->so_state & (SS_ISDISCONNECTING|SS_NBIO)) ==
+			    (SS_ISDISCONNECTING|SS_NBIO))
 				goto drop;
 			while (so->so_state & SS_ISCONNECTED) {
 				error = sowait(so, true, so->so_linger * hz);
@@ -961,7 +962,7 @@
 		}
 		if (space < resid + clen &&
 		    (atomic || space < so->so_snd.sb_lowat || space < clen)) {
-			if (so->so_nbio) {
+			if ((so->so_state & SS_NBIO) || (flags & MSG_NBIO)) {
 				error = EWOULDBLOCK;
 				goto release;
 			}
@@ -1257,7 +1258,8 @@
 		}
 		if (uio->uio_resid == 0)
 			goto release;
-		if (so->so_nbio || (flags & MSG_DONTWAIT)) {
+		if ((so->so_state & SS_NBIO) ||
+		    (flags & (MSG_DONTWAIT|MSG_NBIO))) {
 			error = EWOULDBLOCK;
 			goto release;
 		}

cvs diff -r1.109 -r1.110 src/sys/kern/uipc_socket2.c (expand / switch to context diff)
--- src/sys/kern/uipc_socket2.c 2011/08/31 18:31:03 1.109
+++ src/sys/kern/uipc_socket2.c 2011/12/20 23:56:28 1.110
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket2.c,v 1.109 2011/08/31 18:31:03 plunky Exp $	*/
+/*	$NetBSD: uipc_socket2.c,v 1.110 2011/12/20 23:56:28 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.109 2011/08/31 18:31:03 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.110 2011/12/20 23:56:28 christos Exp $");
 
 #include "opt_mbuftrace.h"
 #include "opt_sb_max.h"
@@ -265,7 +265,6 @@
 	so->so_options = head->so_options &~ SO_ACCEPTCONN;
 	so->so_linger = head->so_linger;
 	so->so_state = head->so_state | SS_NOFDREF;
-	so->so_nbio = head->so_nbio;
 	so->so_proto = head->so_proto;
 	so->so_timeo = head->so_timeo;
 	so->so_pgid = head->so_pgid;

cvs diff -r1.148 -r1.149 src/sys/kern/uipc_syscalls.c (expand / switch to context diff)
--- src/sys/kern/uipc_syscalls.c 2011/11/04 02:13:08 1.148
+++ src/sys/kern/uipc_syscalls.c 2011/12/20 23:56:28 1.149
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_syscalls.c,v 1.148 2011/11/04 02:13:08 christos Exp $	*/
+/*	$NetBSD: uipc_syscalls.c,v 1.149 2011/12/20 23:56:28 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.148 2011/11/04 02:13:08 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.149 2011/12/20 23:56:28 christos Exp $");
 
 #include "opt_pipe.h"
 
@@ -198,7 +198,7 @@
 		error = EINVAL;
 		goto bad;
 	}
-	if (so->so_nbio && so->so_qlen == 0) {
+	if ((so->so_state & SS_NBIO) && so->so_qlen == 0) {
 		error = EWOULDBLOCK;
 		goto bad;
 	}
@@ -367,7 +367,7 @@
 	error = soconnect(so, nam, l);
 	if (error)
 		goto bad;
-	if (so->so_nbio && (so->so_state & SS_ISCONNECTING) != 0) {
+	if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING) != 0) {
 		error = EINPROGRESS;
 		goto out;
 	}

cvs diff -r1.70 -r1.71 src/sys/miscfs/fifofs/fifo_vnops.c (expand / switch to context diff)
--- src/sys/miscfs/fifofs/fifo_vnops.c 2011/08/31 18:31:03 1.70
+++ src/sys/miscfs/fifofs/fifo_vnops.c 2011/12/20 23:56:29 1.71
@@ -1,4 +1,4 @@
-/*	$NetBSD: fifo_vnops.c,v 1.70 2011/08/31 18:31:03 plunky Exp $	*/
+/*	$NetBSD: fifo_vnops.c,v 1.71 2011/12/20 23:56:29 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.70 2011/08/31 18:31:03 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.71 2011/12/20 23:56:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -243,7 +243,7 @@
 	} */ *ap = v;
 	struct uio	*uio;
 	struct socket	*rso;
-	int		error;
+	int		error, sflags;
 	size_t		startresid;
 
 	uio = ap->a_uio;
@@ -256,18 +256,14 @@
 		return (0);
 	startresid = uio->uio_resid;
 	VOP_UNLOCK(ap->a_vp);
-	if (ap->a_ioflag & IO_NDELAY) {
-		/* XXX Bogus, affects other threads. */
-		rso->so_nbio = 1;
-	}
-	error = (*rso->so_receive)(rso, NULL, uio, NULL, NULL, NULL);
+	sflags = (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0;
+	error = (*rso->so_receive)(rso, NULL, uio, NULL, NULL, &sflags);
 	/*
 	 * Clear EOF indication after first such return.
 	 */
-	if (uio->uio_resid == startresid)
+	if (error != EINTR && uio->uio_resid == startresid)
 		rso->so_state &= ~SS_CANTRCVMORE;
 	if (ap->a_ioflag & IO_NDELAY) {
-		rso->so_nbio = 0;
 		if (error == EWOULDBLOCK &&
 		    ap->a_vp->v_fifoinfo->fi_writers == 0)
 			error = 0;
@@ -290,7 +286,7 @@
 		kauth_cred_t	a_cred;
 	} */ *ap = v;
 	struct socket	*wso;
-	int		error;
+	int		error, sflags;
 
 	wso = ap->a_vp->v_fifoinfo->fi_writesock;
 #ifdef DIAGNOSTIC
@@ -298,13 +294,8 @@
 		panic("fifo_write mode");
 #endif
 	VOP_UNLOCK(ap->a_vp);
-	if (ap->a_ioflag & IO_NDELAY) {
-		/* XXX Bogus, affects other threads. */
-		wso->so_nbio = 1;
-	}
-	error = (*wso->so_send)(wso, NULL, ap->a_uio, 0, NULL, 0, curlwp);
-	if (ap->a_ioflag & IO_NDELAY)
-		wso->so_nbio = 0;
+	sflags = (ap->a_ioflag & IO_NDELAY) ? MSG_NBIO : 0;
+	error = (*wso->so_send)(wso, NULL, ap->a_uio, 0, NULL, sflags, curlwp);
 	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
 	return (error);
 }

cvs diff -r1.40 -r1.41 src/sys/netiso/Attic/tp_usrreq.c (expand / switch to context diff)
--- src/sys/netiso/Attic/tp_usrreq.c 2009/03/18 22:08:57 1.40
+++ src/sys/netiso/Attic/tp_usrreq.c 2011/12/20 23:56:29 1.41
@@ -1,4 +1,4 @@
-/*	$NetBSD: tp_usrreq.c,v 1.40 2009/03/18 22:08:57 he Exp $	*/
+/*	$NetBSD: tp_usrreq.c,v 1.41 2011/12/20 23:56:29 christos Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tp_usrreq.c,v 1.40 2009/03/18 22:08:57 he Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tp_usrreq.c,v 1.41 2011/12/20 23:56:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -212,7 +212,7 @@
 		}
 #endif
 		sbunlock(sb);
-		if (so->so_nbio) {
+		if (so->so_state & SS_NBIO) {
 			return EWOULDBLOCK;
 		}
 		sbwait(sb);
@@ -306,7 +306,7 @@
 	 */
 	if (sb->sb_mb) {	/* Anything already in eXpedited data
 				 * sockbuf? */
-		if (so->so_nbio) {
+		if (so->so_state & SS_NBIO) {
 			return EWOULDBLOCK;
 		}
 		while (sb->sb_mb) {

cvs diff -r1.100 -r1.101 src/sys/sys/socket.h (expand / switch to context diff)
--- src/sys/sys/socket.h 2011/06/26 16:43:12 1.100
+++ src/sys/sys/socket.h 2011/12/20 23:56:29 1.101
@@ -1,4 +1,4 @@
-/*	$NetBSD: socket.h,v 1.100 2011/06/26 16:43:12 christos Exp $	*/
+/*	$NetBSD: socket.h,v 1.101 2011/12/20 23:56:29 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -492,6 +492,7 @@
 #define	MSG_NOSIGNAL	0x0400		/* do not generate SIGPIPE on EOF */
 #if defined(_NETBSD_SOURCE)
 #define	MSG_CMSG_CLOEXEC 0x0800		/* close on exec receiving fd */
+#define	MSG_NBIO	0x1000		/* use non-blocking I/O */
 #endif
 
 /* Extra flags used internally only */

cvs diff -r1.126 -r1.127 src/sys/sys/socketvar.h (expand / switch to context diff)
--- src/sys/sys/socketvar.h 2011/07/02 17:53:51 1.126
+++ src/sys/sys/socketvar.h 2011/12/20 23:56:29 1.127
@@ -1,4 +1,4 @@
-/*	$NetBSD: socketvar.h,v 1.126 2011/07/02 17:53:51 bouyer Exp $	*/
+/*	$NetBSD: socketvar.h,v 1.127 2011/12/20 23:56:29 christos Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -128,7 +128,6 @@
 	short		so_options;	/* from socket call, see socket.h */
 	u_short		so_linger;	/* time to linger while closing */
 	short		so_state;	/* internal state flags SS_*, below */
-	int		so_nbio;	/* non-blocking I/O enabled */
 	void		*so_pcb;	/* protocol control block */
 	const struct protosw *so_proto;	/* protocol handle */
 /*
@@ -210,6 +209,7 @@
 					 * more data coming
 					 */
 #define	SS_ISAPIPE 		0x1000	/* socket is implementing a pipe */
+#define	SS_NBIO			0x2000	/* socket is in non blocking I/O */
 
 #ifdef _KERNEL