From owner-freebsd-current Thu Feb 4 14:30:28 1999 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id OAA02462 for freebsd-current-outgoing; Thu, 4 Feb 1999 14:30:28 -0800 (PST) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from apollo.backplane.com (apollo.backplane.com [209.157.86.2]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id OAA02451 for ; Thu, 4 Feb 1999 14:30:26 -0800 (PST) (envelope-from dillon@apollo.backplane.com) Received: (from dillon@localhost) by apollo.backplane.com (8.9.2/8.9.1) id OAA90906; Thu, 4 Feb 1999 14:30:26 -0800 (PST) (envelope-from dillon) Date: Thu, 4 Feb 1999 14:30:26 -0800 (PST) From: Matthew Dillon Message-Id: <199902042230.OAA90906@apollo.backplane.com> To: current@FreeBSD.ORG Subject: Re: Bug in piperd References: <199902042219.OAA90785@apollo.backplane.com> Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Updated patch - one must also check to see if any new data has entered the pipe after locking it in case the lock blocked. ( this patch FYI only, the problem occurs unoften enough that you can afford to wait until I commit it ). -Matt Index: sys_pipe.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sys_pipe.c,v retrieving revision 1.49 diff -u -r1.49 sys_pipe.c --- sys_pipe.c 1999/01/28 00:57:47 1.49 +++ sys_pipe.c 1999/02/04 22:24:42 @@ -381,12 +381,39 @@ #endif } else { /* + * If there is no more to read in the pipe, reset + * its pointers to the beginning. This improves + * cache hit stats. + * + * We get this over with now because it may block + * and cause the state to change out from under us, + * rather then have to re-test the state both before + * and after this fragment. + */ + + if ((error = pipelock(rpipe,1)) == 0) { + if (rpipe->pipe_buffer.cnt == 0) { + rpipe->pipe_buffer.in = 0; + rpipe->pipe_buffer.out = 0; + } + pipeunlock(rpipe); + + /* + * If pipe filled up due to pipelock + * blocking, loop back up. + */ + if (rpipe->pipe_buffer.cnt > 0) + continue; + } + + /* * detect EOF condition */ if (rpipe->pipe_state & PIPE_EOF) { /* XXX error = ? */ break; } + /* * If the "write-side" has been blocked, wake it up now. */ @@ -394,34 +421,26 @@ rpipe->pipe_state &= ~PIPE_WANTW; wakeup(rpipe); } - if (nread > 0) + + /* + * break if error (signal via pipelock), or if some + * data was read + */ + if (error || nread > 0) break; + /* + * Handle non-blocking mode operation + */ + if (fp->f_flag & FNONBLOCK) { error = EAGAIN; break; } /* - * If there is no more to read in the pipe, reset - * its pointers to the beginning. This improves - * cache hit stats. + * Wait for more data */ - - if ((error = pipelock(rpipe,1)) == 0) { - if (rpipe->pipe_buffer.cnt == 0) { - rpipe->pipe_buffer.in = 0; - rpipe->pipe_buffer.out = 0; - } - pipeunlock(rpipe); - } else { - break; - } - - if (rpipe->pipe_state & PIPE_WANTW) { - rpipe->pipe_state &= ~PIPE_WANTW; - wakeup(rpipe); - } rpipe->pipe_state |= PIPE_WANTR; if ((error = tsleep(rpipe, PRIBIO|PCATCH, "piperd", 0)) != 0) { To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message