summaryrefslogtreecommitdiff
path: root/sys/fs/fifofs/fifo_vnops.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2009-07-07 09:43:44 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2009-07-07 09:43:44 +0000
commit7f5dff50646e2eb5e7cf490c0a73f49f85ab5ce1 (patch)
treefa963c164b557f57ea4c0183ad1527b57d286d89 /sys/fs/fifofs/fifo_vnops.c
parent55b57bd2746a468fdc3de857b95d4037c5cda593 (diff)
Notes
Diffstat (limited to 'sys/fs/fifofs/fifo_vnops.c')
-rw-r--r--sys/fs/fifofs/fifo_vnops.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index d328f3b4289a..25436c70f458 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -84,6 +84,7 @@ struct fifoinfo {
struct socket *fi_writesock;
long fi_readers;
long fi_writers;
+ int fi_wgen;
};
static vop_print_t fifo_print;
@@ -232,6 +233,7 @@ fail1:
sowwakeup(fip->fi_writesock);
}
}
+ fp->f_seqcount = fip->fi_wgen - fip->fi_writers;
}
if (ap->a_mode & FWRITE) {
if ((ap->a_mode & O_NONBLOCK) && fip->fi_readers == 0) {
@@ -279,6 +281,9 @@ fail1:
fip->fi_writers--;
if (fip->fi_writers == 0) {
socantrcvmore(fip->fi_readsock);
+ mtx_lock(&fifo_mtx);
+ fip->fi_wgen++;
+ mtx_unlock(&fifo_mtx);
fifo_cleanup(vp);
}
return (error);
@@ -395,8 +400,12 @@ fifo_close(ap)
}
if (ap->a_fflag & FWRITE) {
fip->fi_writers--;
- if (fip->fi_writers == 0)
+ if (fip->fi_writers == 0) {
socantrcvmore(fip->fi_readsock);
+ mtx_lock(&fifo_mtx);
+ fip->fi_wgen++;
+ mtx_unlock(&fifo_mtx);
+ }
}
fifo_cleanup(vp);
return (0);
@@ -634,28 +643,13 @@ fifo_poll_f(struct file *fp, int events, struct ucred *cred, struct thread *td)
levents = events &
(POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND);
if ((fp->f_flag & FREAD) && levents) {
- /*
- * If POLLIN or POLLRDNORM is requested and POLLINIGNEOF is
- * not, then convert the first two to the last one. This
- * tells the socket poll function to ignore EOF so that we
- * block if there is no writer (and no data). Callers can
- * set POLLINIGNEOF to get non-blocking behavior.
- */
- if (levents & (POLLIN | POLLRDNORM) &&
- !(levents & POLLINIGNEOF)) {
- levents &= ~(POLLIN | POLLRDNORM);
- levents |= POLLINIGNEOF;
- }
-
filetmp.f_data = fip->fi_readsock;
filetmp.f_cred = cred;
+ mtx_lock(&fifo_mtx);
+ if (fp->f_seqcount == fip->fi_wgen)
+ levents |= POLLINIGNEOF;
+ mtx_unlock(&fifo_mtx);
revents |= soo_poll(&filetmp, levents, cred, td);
-
- /* Reverse the above conversion. */
- if ((revents & POLLINIGNEOF) && !(events & POLLINIGNEOF)) {
- revents |= (events & (POLLIN | POLLRDNORM));
- revents &= ~POLLINIGNEOF;
- }
}
levents = events & (POLLOUT | POLLWRNORM | POLLWRBAND);
if ((fp->f_flag & FWRITE) && levents) {