From owner-svn-src-head@FreeBSD.ORG Tue Jul 31 05:48:36 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 53E3B1065670; Tue, 31 Jul 2012 05:48:36 +0000 (UTC) (envelope-from davidxu@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 34C4D8FC0A; Tue, 31 Jul 2012 05:48:36 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q6V5masR091628; Tue, 31 Jul 2012 05:48:36 GMT (envelope-from davidxu@svn.freebsd.org) Received: (from davidxu@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q6V5mZHf091624; Tue, 31 Jul 2012 05:48:35 GMT (envelope-from davidxu@svn.freebsd.org) Message-Id: <201207310548.q6V5mZHf091624@svn.freebsd.org> From: David Xu Date: Tue, 31 Jul 2012 05:48:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r238936 - in head/sys: fs/fifofs kern sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 31 Jul 2012 05:48:36 -0000 Author: davidxu Date: Tue Jul 31 05:48:35 2012 New Revision: 238936 URL: http://svn.freebsd.org/changeset/base/238936 Log: I am comparing current pipe code with the one in 8.3-STABLE r236165, I found 8.3 is a history BSD version using socket to implement FIFO pipe, it uses per-file seqcount to compare with writer generation stored in per-pipe object. The concept is after all writers are gone, the pipe enters next generation, all old readers have not closed the pipe should get the indication that the pipe is disconnected, result is they should get EPIPE, SIGPIPE or get POLLHUP in poll(). But newcomer should not know that previous writters were gone, it should treat it as a fresh session. I am trying to bring back FIFO pipe to history behavior. It is still unclear that if single EOF flag can represent SBS_CANTSENDMORE and SBS_CANTRCVMORE which socket-based version is using, but I have run the poll regression test in tool directory, output is same as the one on 8.3-STABLE now. I think the output "not ok 18 FIFO state 6b: poll result 0 expected 1. expected POLLHUP; got 0" might be bogus, because newcomer should not know that old writers were gone. I got the same behavior on Linux. Our implementation always return POLLIN for disconnected pipe even it should return POLLHUP, but I think it is not wise to remove POLLIN for compatible reason, this is our history behavior. Regression test: /usr/src/tools/regression/poll Modified: head/sys/fs/fifofs/fifo_vnops.c head/sys/kern/sys_pipe.c head/sys/sys/pipe.h Modified: head/sys/fs/fifofs/fifo_vnops.c ============================================================================== --- head/sys/fs/fifofs/fifo_vnops.c Tue Jul 31 05:44:03 2012 (r238935) +++ head/sys/fs/fifofs/fifo_vnops.c Tue Jul 31 05:48:35 2012 (r238936) @@ -59,23 +59,13 @@ * Notes about locking: * - fi_pipe is invariant since init time. * - fi_readers and fi_writers are protected by the vnode lock. - * - fi_wgen and fi_seqcount are protected by the pipe mutex. */ struct fifoinfo { struct pipe *fi_pipe; long fi_readers; long fi_writers; - int fi_wgen; - int fi_seqcount; }; -#define FIFO_UPDWGEN(fip, pip) do { \ - if ((fip)->fi_wgen == (fip)->fi_seqcount) \ - (pip)->pipe_state |= PIPE_SAMEWGEN; \ - else \ - (pip)->pipe_state &= ~PIPE_SAMEWGEN; \ -} while (0) - static vop_print_t fifo_print; static vop_open_t fifo_open; static vop_close_t fifo_close; @@ -161,7 +151,7 @@ fifo_open(ap) return (error); fip = malloc(sizeof(*fip), M_VNODE, M_WAITOK); fip->fi_pipe = fpipe; - fip->fi_wgen = fip->fi_readers = fip->fi_writers = 0; + fpipe->pipe_wgen = fip->fi_readers = fip->fi_writers = 0; KASSERT(vp->v_fifoinfo == NULL, ("fifo_open: v_fifoinfo race")); vp->v_fifoinfo = fip; } @@ -181,8 +171,7 @@ fifo_open(ap) if (fip->fi_writers > 0) wakeup(&fip->fi_writers); } - fip->fi_seqcount = fip->fi_wgen - fip->fi_writers; - FIFO_UPDWGEN(fip, fpipe); + fp->f_seqcount = fpipe->pipe_wgen - fip->fi_writers; } if (ap->a_mode & FWRITE) { if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) { @@ -235,8 +224,7 @@ fifo_open(ap) fpipe->pipe_state |= PIPE_EOF; if (fpipe->pipe_state & PIPE_WANTR) wakeup(fpipe); - fip->fi_wgen++; - FIFO_UPDWGEN(fip, fpipe); + fpipe->pipe_wgen++; PIPE_UNLOCK(fpipe); fifo_cleanup(vp); } @@ -300,8 +288,7 @@ fifo_close(ap) cpipe->pipe_state &= ~PIPE_WANTR; wakeup(cpipe); } - fip->fi_wgen++; - FIFO_UPDWGEN(fip, cpipe); + cpipe->pipe_wgen++; pipeselwakeup(cpipe); PIPE_UNLOCK(cpipe); } Modified: head/sys/kern/sys_pipe.c ============================================================================== --- head/sys/kern/sys_pipe.c Tue Jul 31 05:44:03 2012 (r238935) +++ head/sys/kern/sys_pipe.c Tue Jul 31 05:48:35 2012 (r238936) @@ -1442,7 +1442,7 @@ pipe_poll(fp, events, active_cred, td) levents = events & (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND); if (rpipe->pipe_state & PIPE_NAMED && fp->f_flag & FREAD && levents && - rpipe->pipe_state & PIPE_SAMEWGEN) + fp->f_seqcount == rpipe->pipe_wgen) events |= POLLINIGNEOF; if ((events & POLLINIGNEOF) == 0) { Modified: head/sys/sys/pipe.h ============================================================================== --- head/sys/sys/pipe.h Tue Jul 31 05:44:03 2012 (r238935) +++ head/sys/sys/pipe.h Tue Jul 31 05:48:35 2012 (r238936) @@ -96,7 +96,6 @@ struct pipemapping { #define PIPE_DIRECTW 0x400 /* Pipe direct write active. */ #define PIPE_DIRECTOK 0x800 /* Direct mode ok. */ #define PIPE_NAMED 0x1000 /* Is a named pipe. */ -#define PIPE_SAMEWGEN 0x2000 /* same write generation for named pipes. */ /* * Per-pipe data structure. @@ -115,6 +114,7 @@ struct pipe { u_int pipe_state; /* pipe status info */ int pipe_busy; /* busy flag, mostly to handle rundown sanely */ int pipe_present; /* still present? */ + int pipe_wgen; /* writer generation for named pipe */ ino_t pipe_ino; /* fake inode for stat(2) */ };