View | Details | Raw Unified | Return to bug 224615 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/fs/fifofs/fifo_vnops.c (-2 / +8 lines)
Lines 174-181 fifo_open(ap) Link Here
174
		fip->fi_rgen++;
174
		fip->fi_rgen++;
175
		if (fip->fi_readers == 1) {
175
		if (fip->fi_readers == 1) {
176
			fpipe->pipe_state &= ~PIPE_EOF;
176
			fpipe->pipe_state &= ~PIPE_EOF;
177
			if (fip->fi_writers > 0)
177
			if (fip->fi_writers > 0) {
178
				wakeup(&fip->fi_writers);
178
				wakeup(&fip->fi_writers);
179
				pipeselwakeup(fpipe);
180
			}
179
		}
181
		}
180
		fp->f_pipegen = fpipe->pipe_wgen - fip->fi_writers;
182
		fp->f_pipegen = fpipe->pipe_wgen - fip->fi_writers;
181
	}
183
	}
Lines 190-197 fifo_open(ap) Link Here
190
		fip->fi_wgen++;
192
		fip->fi_wgen++;
191
		if (fip->fi_writers == 1) {
193
		if (fip->fi_writers == 1) {
192
			fpipe->pipe_state &= ~PIPE_EOF;
194
			fpipe->pipe_state &= ~PIPE_EOF;
193
			if (fip->fi_readers > 0)
195
			if (fip->fi_readers > 0) {
194
				wakeup(&fip->fi_readers);
196
				wakeup(&fip->fi_readers);
197
				pipeselwakeup(fpipe);
198
			}
195
		}
199
		}
196
	}
200
	}
197
	if ((ap->a_mode & O_NONBLOCK) == 0) {
201
	if ((ap->a_mode & O_NONBLOCK) == 0) {
Lines 210-215 fifo_open(ap) Link Here
210
					fpipe->pipe_state |= PIPE_EOF;
214
					fpipe->pipe_state |= PIPE_EOF;
211
					if (fpipe->pipe_state & PIPE_WANTW)
215
					if (fpipe->pipe_state & PIPE_WANTW)
212
						wakeup(fpipe);
216
						wakeup(fpipe);
217
					pipeselwakeup(fpipe);
213
					PIPE_UNLOCK(fpipe);
218
					PIPE_UNLOCK(fpipe);
214
					fifo_cleanup(vp);
219
					fifo_cleanup(vp);
215
				}
220
				}
Lines 238-243 fifo_open(ap) Link Here
238
					if (fpipe->pipe_state & PIPE_WANTR)
243
					if (fpipe->pipe_state & PIPE_WANTR)
239
						wakeup(fpipe);
244
						wakeup(fpipe);
240
					fpipe->pipe_wgen++;
245
					fpipe->pipe_wgen++;
246
					pipeselwakeup(fpipe);
241
					PIPE_UNLOCK(fpipe);
247
					PIPE_UNLOCK(fpipe);
242
					fifo_cleanup(vp);
248
					fifo_cleanup(vp);
243
				}
249
				}
(-)b/sys/kern/sys_pipe.c (-21 / +32 lines)
Lines 824-830 pipe_read(struct file *fp, struct uio *uio, struct ucred *active_cred, Link Here
824
		}
824
		}
825
	}
825
	}
826
826
827
	if ((rpipe->pipe_buffer.size - rpipe->pipe_buffer.cnt) >= PIPE_BUF)
827
	/*
828
	 * Only wake up writers if there was actually something read.
829
	 * Otherwise, when calling read(2) at EOF, a spurious wakeup occurs
830
	 * that might lead to issues like PR 203366.
831
	 */
832
	if (nread > 0 &&
833
	    (rpipe->pipe_buffer.size - rpipe->pipe_buffer.cnt) >= PIPE_BUF)
828
		pipeselwakeup(rpipe);
834
		pipeselwakeup(rpipe);
829
835
830
	PIPE_UNLOCK(rpipe);
836
	PIPE_UNLOCK(rpipe);
Lines 1430-1436 pipe_poll(struct file *fp, int events, struct ucred *active_cred, Link Here
1430
1436
1431
	if ((events & POLLINIGNEOF) == 0) {
1437
	if ((events & POLLINIGNEOF) == 0) {
1432
		if (rpipe->pipe_state & PIPE_EOF) {
1438
		if (rpipe->pipe_state & PIPE_EOF) {
1433
			revents |= (events & (POLLIN | POLLRDNORM));
1439
			if (fp->f_flag & FREAD)
1440
				revents |= (events & (POLLIN | POLLRDNORM));
1434
			if (wpipe->pipe_present != PIPE_ACTIVE ||
1441
			if (wpipe->pipe_present != PIPE_ACTIVE ||
1435
			    (wpipe->pipe_state & PIPE_EOF))
1442
			    (wpipe->pipe_state & PIPE_EOF))
1436
				revents |= POLLHUP;
1443
				revents |= POLLHUP;
Lines 1605-1612 pipeclose(struct pipe *cpipe) Link Here
1605
	pipelock(cpipe, 0);
1612
	pipelock(cpipe, 0);
1606
	pp = cpipe->pipe_pair;
1613
	pp = cpipe->pipe_pair;
1607
1614
1608
	pipeselwakeup(cpipe);
1609
1610
	/*
1615
	/*
1611
	 * If the other side is blocked, wake it up saying that
1616
	 * If the other side is blocked, wake it up saying that
1612
	 * we want to close it down.
1617
	 * we want to close it down.
Lines 1620-1635 pipeclose(struct pipe *cpipe) Link Here
1620
		pipelock(cpipe, 0);
1625
		pipelock(cpipe, 0);
1621
	}
1626
	}
1622
1627
1628
	pipeselwakeup(cpipe);
1629
1623
	/*
1630
	/*
1624
	 * Disconnect from peer, if any.
1631
	 * Disconnect from peer, if any.
1625
	 */
1632
	 */
1626
	ppipe = cpipe->pipe_peer;
1633
	ppipe = cpipe->pipe_peer;
1627
	if (ppipe->pipe_present == PIPE_ACTIVE) {
1634
	if (ppipe->pipe_present == PIPE_ACTIVE) {
1628
		pipeselwakeup(ppipe);
1629
1630
		ppipe->pipe_state |= PIPE_EOF;
1635
		ppipe->pipe_state |= PIPE_EOF;
1631
		wakeup(ppipe);
1636
		wakeup(ppipe);
1632
		KNOTE_LOCKED(&ppipe->pipe_sel.si_note, 0);
1637
		pipeselwakeup(ppipe);
1633
	}
1638
	}
1634
1639
1635
	/*
1640
	/*
Lines 1727-1749 filt_pipedetach(struct knote *kn) Link Here
1727
static int
1732
static int
1728
filt_piperead(struct knote *kn, long hint)
1733
filt_piperead(struct knote *kn, long hint)
1729
{
1734
{
1735
	struct file *fp = kn->kn_fp;
1730
	struct pipe *rpipe = kn->kn_hook;
1736
	struct pipe *rpipe = kn->kn_hook;
1731
	struct pipe *wpipe = rpipe->pipe_peer;
1732
	int ret;
1733
1737
1734
	PIPE_LOCK_ASSERT(rpipe, MA_OWNED);
1738
	PIPE_LOCK_ASSERT(rpipe, MA_OWNED);
1735
	kn->kn_data = rpipe->pipe_buffer.cnt;
1739
	kn->kn_data = rpipe->pipe_buffer.cnt;
1736
	if (kn->kn_data == 0)
1740
	if (kn->kn_data == 0)
1737
		kn->kn_data = rpipe->pipe_map.cnt;
1741
		kn->kn_data = rpipe->pipe_map.cnt;
1738
1742
1739
	if ((rpipe->pipe_state & PIPE_EOF) ||
1743
	if ((rpipe->pipe_state & PIPE_EOF) &&
1740
	    wpipe->pipe_present != PIPE_ACTIVE ||
1744
	    !((rpipe->pipe_state & PIPE_NAMED) &&
1741
	    (wpipe->pipe_state & PIPE_EOF)) {
1745
	        (fp->f_seqcount == rpipe->pipe_wgen))) {
1742
		kn->kn_flags |= EV_EOF;
1746
		kn->kn_flags |= EV_EOF;
1743
		return (1);
1747
		return (1);
1744
	}
1748
	}
1745
	ret = kn->kn_data > 0;
1749
	kn->kn_flags &= ~EV_EOF;
1746
	return ret;
1750
	return (kn->kn_data > 0);
1747
}
1751
}
1748
1752
1749
/*ARGSUSED*/
1753
/*ARGSUSED*/
Lines 1757-1774 filt_pipewrite(struct knote *kn, long hint) Link Here
1757
	 * knlist and the list lock (i.e., the pipe lock) is therefore not held.
1761
	 * knlist and the list lock (i.e., the pipe lock) is therefore not held.
1758
	 */
1762
	 */
1759
	wpipe = kn->kn_hook;
1763
	wpipe = kn->kn_hook;
1764
1765
	if (wpipe->pipe_present == PIPE_ACTIVE) {
1766
		PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
1767
	}
1768
1769
	if (wpipe->pipe_state & PIPE_DIRECTW) {
1770
		kn->kn_data = 0;
1771
	} else if (wpipe->pipe_buffer.size > 0) {
1772
		kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
1773
	} else {
1774
		kn->kn_data = PIPE_BUF;
1775
	}
1776
1760
	if (wpipe->pipe_present != PIPE_ACTIVE ||
1777
	if (wpipe->pipe_present != PIPE_ACTIVE ||
1761
	    (wpipe->pipe_state & PIPE_EOF)) {
1778
	    (wpipe->pipe_state & PIPE_EOF)) {
1762
		kn->kn_data = 0;
1763
		kn->kn_flags |= EV_EOF;
1779
		kn->kn_flags |= EV_EOF;
1764
		return (1);
1780
		return (1);
1765
	}
1781
	}
1766
	PIPE_LOCK_ASSERT(wpipe, MA_OWNED);
1782
	kn->kn_flags &= ~EV_EOF;
1767
	kn->kn_data = (wpipe->pipe_buffer.size > 0) ?
1768
	    (wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) : PIPE_BUF;
1769
	if (wpipe->pipe_state & PIPE_DIRECTW)
1770
		kn->kn_data = 0;
1771
1772
	return (kn->kn_data >= PIPE_BUF);
1783
	return (kn->kn_data >= PIPE_BUF);
1773
}
1784
}
1774
1785
(-)b/tools/regression/poll/pipepoll.c (+26 lines)
Lines 1-5 Link Here
1
/* $FreeBSD$ */
1
/* $FreeBSD$ */
2
2
3
#include <sys/event.h>
3
#include <sys/poll.h>
4
#include <sys/poll.h>
4
#include <sys/socket.h>
5
#include <sys/socket.h>
5
#include <sys/stat.h>
6
#include <sys/stat.h>
Lines 202-207 child(int fd, int num) Link Here
202
		if ((res = poll(&pfd, 1, 0)) < 0)
203
		if ((res = poll(&pfd, 1, 0)) < 0)
203
			err(1, "poll");
204
			err(1, "poll");
204
		report(num++, "6b", POLLHUP, pfd.revents, res, 1);
205
		report(num++, "6b", POLLHUP, pfd.revents, res, 1);
206
207
		int kq = kqueue();
208
209
		struct kevent kev;
210
		EV_SET(&kev, fd2, EVFILT_READ, EV_ADD, 0, 0, 0);
211
		if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0) {
212
			err(1, "kevent");
213
		}
214
215
		int n;
216
		struct timespec ts = { 0, 0 };
217
		if ((n = kevent(kq, NULL, 0, &kev, 1, &ts)) < 0) {
218
			err(1, "kevent");
219
		}
220
		for (int i = 0; i < n; ++i) {
221
			fprintf(stderr, "got event: %d\n", (int)kev.filter);
222
			fprintf(stderr, " fd: %d\n", (int)kev.ident);
223
			fprintf(stderr, " data: %d\n", (int)kev.data);
224
			fprintf(stderr, " flags: %x\n", (unsigned)kev.flags);
225
			fprintf(stderr, " fflags: %x\n", (unsigned)kev.fflags);
226
		}
227
		if (n == 0) {
228
			fprintf(stderr, "got no events\n");
229
		}
230
205
		pfd.fd = fd;
231
		pfd.fd = fd;
206
		if ((res = poll(&pfd, 1, 0)) < 0)
232
		if ((res = poll(&pfd, 1, 0)) < 0)
207
			err(1, "poll");
233
			err(1, "poll");

Return to bug 224615