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 |
|