summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2012-07-31 05:48:35 +0000
committerdavidxu <davidxu@FreeBSD.org>2012-07-31 05:48:35 +0000
commitc8c77f184e05b058ac40c9c1e4ecb44628ee06fe (patch)
tree5639cee7976a84e093e17117a4da2ed8e242033a /sys
parent712f939cb3d3a683ddbac7fdbf56303f087597ee (diff)
downloadFreeBSD-src-c8c77f184e05b058ac40c9c1e4ecb44628ee06fe.zip
FreeBSD-src-c8c77f184e05b058ac40c9c1e4ecb44628ee06fe.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/fifofs/fifo_vnops.c21
-rw-r--r--sys/kern/sys_pipe.c2
-rw-r--r--sys/sys/pipe.h2
3 files changed, 6 insertions, 19 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index 859f68c..bdb1367 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -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);
}
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 02664e9..338256c 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -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) {
diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h
index f0029a8..dfe7f2f 100644
--- a/sys/sys/pipe.h
+++ b/sys/sys/pipe.h
@@ -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) */
};
OpenPOWER on IntegriCloud