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

Collapse All | Expand All

(-)b/sys/fs/fifofs/fifo_vnops.c (-2 / +6 lines)
Lines 171-178 fifo_open(ap) Link Here
171
		fip->fi_rgen++;
171
		fip->fi_rgen++;
172
		if (fip->fi_readers == 1) {
172
		if (fip->fi_readers == 1) {
173
			fpipe->pipe_state &= ~PIPE_EOF;
173
			fpipe->pipe_state &= ~PIPE_EOF;
174
			if (fip->fi_writers > 0)
174
			if (fip->fi_writers > 0) {
175
				wakeup(&fip->fi_writers);
175
				wakeup(&fip->fi_writers);
176
				pipeselwakeup(fpipe);
177
			}
176
		}
178
		}
177
		fp->f_seqcount = fpipe->pipe_wgen - fip->fi_writers;
179
		fp->f_seqcount = fpipe->pipe_wgen - fip->fi_writers;
178
	}
180
	}
Lines 187-194 fifo_open(ap) Link Here
187
		fip->fi_wgen++;
189
		fip->fi_wgen++;
188
		if (fip->fi_writers == 1) {
190
		if (fip->fi_writers == 1) {
189
			fpipe->pipe_state &= ~PIPE_EOF;
191
			fpipe->pipe_state &= ~PIPE_EOF;
190
			if (fip->fi_readers > 0)
192
			if (fip->fi_readers > 0) {
191
				wakeup(&fip->fi_readers);
193
				wakeup(&fip->fi_readers);
194
				pipeselwakeup(fpipe);
195
			}
192
		}
196
		}
193
	}
197
	}
194
	if ((ap->a_mode & O_NONBLOCK) == 0) {
198
	if ((ap->a_mode & O_NONBLOCK) == 0) {
(-)b/sys/kern/sys_pipe.c (-9 / +16 lines)
Lines 823-829 pipe_read(fp, uio, active_cred, flags, td) Link Here
823
		}
823
		}
824
	}
824
	}
825
825
826
	if ((rpipe->pipe_buffer.size - rpipe->pipe_buffer.cnt) >= PIPE_BUF)
826
	/*
827
	 * Only wake up writers if there was actually something read.
828
	 * Otherwise, when calling read(2) at EOF, a spurious wakeup occurs
829
	 * that might lead to issues like PR 203366.
830
	 */
831
	if (nread > 0 &&
832
	    (rpipe->pipe_buffer.size - rpipe->pipe_buffer.cnt) >= PIPE_BUF)
827
		pipeselwakeup(rpipe);
833
		pipeselwakeup(rpipe);
828
834
829
	PIPE_UNLOCK(rpipe);
835
	PIPE_UNLOCK(rpipe);
Lines 1461-1467 pipe_poll(fp, events, active_cred, td) Link Here
1461
1467
1462
	if ((events & POLLINIGNEOF) == 0) {
1468
	if ((events & POLLINIGNEOF) == 0) {
1463
		if (rpipe->pipe_state & PIPE_EOF) {
1469
		if (rpipe->pipe_state & PIPE_EOF) {
1464
			revents |= (events & (POLLIN | POLLRDNORM));
1470
			if (fp->f_flag & FREAD)
1471
				revents |= (events & (POLLIN | POLLRDNORM));
1465
			if (wpipe->pipe_present != PIPE_ACTIVE ||
1472
			if (wpipe->pipe_present != PIPE_ACTIVE ||
1466
			    (wpipe->pipe_state & PIPE_EOF))
1473
			    (wpipe->pipe_state & PIPE_EOF))
1467
				revents |= POLLHUP;
1474
				revents |= POLLHUP;
Lines 1788-1810 filt_pipedetach(struct knote *kn) Link Here
1788
static int
1795
static int
1789
filt_piperead(struct knote *kn, long hint)
1796
filt_piperead(struct knote *kn, long hint)
1790
{
1797
{
1798
	struct file *fp = kn->kn_fp;
1791
	struct pipe *rpipe = kn->kn_hook;
1799
	struct pipe *rpipe = kn->kn_hook;
1792
	struct pipe *wpipe = rpipe->pipe_peer;
1793
	int ret;
1794
1800
1795
	PIPE_LOCK_ASSERT(rpipe, MA_OWNED);
1801
	PIPE_LOCK_ASSERT(rpipe, MA_OWNED);
1796
	kn->kn_data = rpipe->pipe_buffer.cnt;
1802
	kn->kn_data = rpipe->pipe_buffer.cnt;
1797
	if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW))
1803
	if ((kn->kn_data == 0) && (rpipe->pipe_state & PIPE_DIRECTW))
1798
		kn->kn_data = rpipe->pipe_map.cnt;
1804
		kn->kn_data = rpipe->pipe_map.cnt;
1799
1805
1800
	if ((rpipe->pipe_state & PIPE_EOF) ||
1806
	if ((rpipe->pipe_state & PIPE_EOF) &&
1801
	    wpipe->pipe_present != PIPE_ACTIVE ||
1807
	    !((rpipe->pipe_state & PIPE_NAMED) &&
1802
	    (wpipe->pipe_state & PIPE_EOF)) {
1808
	        (fp->f_seqcount == rpipe->pipe_wgen))) {
1803
		kn->kn_flags |= EV_EOF;
1809
		kn->kn_flags |= EV_EOF;
1804
		return (1);
1810
		return (1);
1805
	}
1811
	}
1806
	ret = kn->kn_data > 0;
1812
	kn->kn_flags &= ~EV_EOF;
1807
	return ret;
1813
	return (kn->kn_data > 0);
1808
}
1814
}
1809
1815
1810
/*ARGSUSED*/
1816
/*ARGSUSED*/
Lines 1821-1826 filt_pipewrite(struct knote *kn, long hint) Link Here
1821
		kn->kn_flags |= EV_EOF;
1827
		kn->kn_flags |= EV_EOF;
1822
		return (1);
1828
		return (1);
1823
	}
1829
	}
1830
	kn->kn_flags &= ~EV_EOF;
1824
	kn->kn_data = (wpipe->pipe_buffer.size > 0) ?
1831
	kn->kn_data = (wpipe->pipe_buffer.size > 0) ?
1825
	    (wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) : PIPE_BUF;
1832
	    (wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) : PIPE_BUF;
1826
	if (wpipe->pipe_state & PIPE_DIRECTW)
1833
	if (wpipe->pipe_state & PIPE_DIRECTW)

Return to bug 203366