PIPE - Fix a blocking race.
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 16 Aug 2009 03:56:04 +0000 (20:56 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 16 Aug 2009 03:56:04 +0000 (20:56 -0700)
* A pipe can get stuck in "pipewr" due to a race caused by a selwakeup()
  before a tsleep().  Fix the race.

sys/kern/sys_pipe.c

index 97a219e..bf24ac2 100644 (file)
@@ -871,10 +871,11 @@ pipe_write(struct file *fp, struct uio *uio, struct ucred *cred, int fflags)
                 * wake up select/poll.
                 */
                if (space == 0) {
-                       pipeselwakeup(wpipe);
-                       ++wpipe->pipe_wantwcnt;
                        wpipe->pipe_state |= PIPE_WANTW;
-                       error = tsleep(wpipe, PCATCH, "pipewr", 0);
+                       ++wpipe->pipe_wantwcnt;
+                       pipeselwakeup(wpipe);
+                       if (wpipe->pipe_state & PIPE_WANTW)
+                               error = tsleep(wpipe, PCATCH, "pipewr", 0);
                        ++pipe_wblocked_count;
                }
                lwkt_reltoken(&rlock);