Module Name:    src
Committed By:   dsl
Date:           Sun Dec 13 20:02:23 UTC 2009

Modified Files:
        src/sys/kern: sys_pipe.c

Log Message:
Another, better, fix for PR/26567.
Only sleep once within each pipe_read/pipe_write call.
If there is no data/space available after we wakeup return ERESTART so
then the 'fd' number is validated again.
A simple broadcast of the cvs is then enough to evict the correct threads
when close() is called from an active thread.


To generate a diff of this commit:
cvs rdiff -u -r1.124 -r1.125 src/sys/kern/sys_pipe.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/sys_pipe.c
diff -u src/sys/kern/sys_pipe.c:1.124 src/sys/kern/sys_pipe.c:1.125
--- src/sys/kern/sys_pipe.c:1.124	Sun Dec 13 18:27:02 2009
+++ src/sys/kern/sys_pipe.c	Sun Dec 13 20:02:23 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_pipe.c,v 1.124 2009/12/13 18:27:02 dsl Exp $	*/
+/*	$NetBSD: sys_pipe.c,v 1.125 2009/12/13 20:02:23 dsl Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.124 2009/12/13 18:27:02 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_pipe.c,v 1.125 2009/12/13 20:02:23 dsl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -449,6 +449,7 @@
 	size_t nread = 0;
 	size_t size;
 	size_t ocnt;
+	int slept = 0;
 
 	mutex_enter(lock);
 	++rpipe->pipe_busy;
@@ -566,6 +567,7 @@
 		if ((rpipe->pipe_state & PIPE_DIRECTR) != 0)
 			goto again;
 
+#if 1   /* XXX (dsl) I'm sure these aren't needed here ... */
 		/*
 		 * We want to read more, wake up select/poll.
 		 */
@@ -575,11 +577,18 @@
 		 * If the "write-side" is blocked, wake it up now.
 		 */
 		cv_broadcast(&rpipe->pipe_wcv);
+#endif
+
+		if (slept) {
+			error = ERESTART;
+			goto unlocked_error;
+		}
 
 		/* Now wait until the pipe is filled */
 		error = cv_wait_sig(&rpipe->pipe_rcv, lock);
 		if (error != 0)
 			goto unlocked_error;
+		slept = 1;
 		goto again;
 	}
 
@@ -814,6 +823,7 @@
 	struct pipebuf *bp;
 	kmutex_t *lock;
 	int error;
+	int slept = 0;
 
 	/* We want to write to our peer */
 	rpipe = (struct pipe *) fp->f_data;
@@ -987,6 +997,11 @@
 			if (bp->cnt)
 				pipeselwakeup(wpipe, wpipe, POLL_IN);
 
+			if (slept) {
+				error = ERESTART;
+				break;
+			}
+
 			pipeunlock(wpipe);
 			error = cv_wait_sig(&wpipe->pipe_wcv, lock);
 			(void)pipelock(wpipe, 0);
@@ -1000,6 +1015,7 @@
 				error = EPIPE;
 				break;
 			}
+			slept = 1;
 		}
 	}
 

Reply via email to