Author: jilles
Date: Wed Dec 14 22:26:39 2011
New Revision: 228510
URL: http://svn.freebsd.org/changeset/base/228510

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

Modified:
  head/sys/kern/sys_pipe.c

Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c    Wed Dec 14 22:22:19 2011        (r228509)
+++ head/sys/kern/sys_pipe.c    Wed Dec 14 22:26:39 2011        (r228510)
@@ -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 hi
                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;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to