Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Another, better, fix for PR/26567.



details:   https://anonhg.NetBSD.org/src/rev/c964f660692d
branches:  trunk
changeset: 749963:c964f660692d
user:      dsl <dsl%NetBSD.org@localhost>
date:      Sun Dec 13 20:02:23 2009 +0000

description:
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.

diffstat:

 sys/kern/sys_pipe.c |  20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diffs (81 lines):

diff -r 37f419639061 -r c964f660692d sys/kern/sys_pipe.c
--- a/sys/kern/sys_pipe.c       Sun Dec 13 19:20:17 2009 +0000
+++ b/sys/kern/sys_pipe.c       Sun Dec 13 20:02:23 2009 +0000
@@ -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;
                }
        }
 



Home | Main Index | Thread Index | Old Index