Fix select/poll/kqueue for write on reverse direction before first write.
The reverse direction of a pipe is lazily allocated on the first write in that direction (because pipes are usually used in one direction only). A special case is needed to ensure the pipe appears writable before the first write because there are 0 bytes of pending data in 0 bytes of buffer space at that point, leaving 0 bytes of data that can be written with the normal code. Note that the first write returns [ENOMEM] if kern.ipc.maxpipekva is exceeded and does not block or return [EAGAIN], so selecting true for write is correct even in that case. PR: kern/93685 Submitted by: gianni MFC after: 2 weeks
This commit is contained in:
parent
fb680e16f4
commit
6d1c58f8a2
@ -1349,7 +1349,8 @@ pipe_poll(fp, events, active_cred, td)
|
||||
if (wpipe->pipe_present != PIPE_ACTIVE ||
|
||||
(wpipe->pipe_state & PIPE_EOF) ||
|
||||
(((wpipe->pipe_state & PIPE_DIRECTW) == 0) &&
|
||||
(wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >= PIPE_BUF))
|
||||
((wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >= PIPE_BUF ||
|
||||
wpipe->pipe_buffer.size == 0)))
|
||||
revents |= events & (POLLOUT | POLLWRNORM);
|
||||
|
||||
if ((events & POLLINIGNEOF) == 0) {
|
||||
@ -1660,7 +1661,8 @@ filt_pipewrite(struct knote *kn, long hint)
|
||||
PIPE_UNLOCK(rpipe);
|
||||
return (1);
|
||||
}
|
||||
kn->kn_data = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
|
||||
kn->kn_data = (wpipe->pipe_buffer.size > 0) ?
|
||||
(wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) : PIPE_BUF;
|
||||
if (wpipe->pipe_state & PIPE_DIRECTW)
|
||||
kn->kn_data = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user