summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_pipe.c
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2007-11-19 15:05:20 +0000
committerdumbbell <dumbbell@FreeBSD.org>2007-11-19 15:05:20 +0000
commitfff090c0118c02baeefd12b4413c8503a4ce0d1b (patch)
treec63af79f0fa66f231cc8872859c517ee90a409b8 /sys/kern/sys_pipe.c
parent764e9c0b5267d42c819658949900c8ad2e0460b7 (diff)
downloadFreeBSD-src-fff090c0118c02baeefd12b4413c8503a4ce0d1b.zip
FreeBSD-src-fff090c0118c02baeefd12b4413c8503a4ce0d1b.tar.gz
The kernel uses two ways to write data on a pipe:
o buffered write, for chunks smaller than PIPE_MINDIRECT bytes o direct write, for everything else A call to writev(2) may receive struct iov of various size and the kernel may have to switch from one solution to the other. Before doing this, it must wake reader processes and any select/poll/kqueue up. This commit fixes a bug where select/poll/kqueue are not triggered when switching from buffered write to direct write. It adds calls to pipeselwakeup(). I give more details on freebsd-arch@: http://lists.freebsd.org/pipermail/freebsd-arch/2007-September/006790.html This should fix issues with Erlang (lang/erlang) and kqueue. Reported by: Rickard Green (Erlang)
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r--sys/kern/sys_pipe.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 4e3f523..2a48583 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -880,6 +880,7 @@ retry:
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
}
+ pipeselwakeup(wpipe);
wpipe->pipe_state |= PIPE_WANTW;
pipeunlock(wpipe);
error = msleep(wpipe, PIPE_MTX(wpipe),
@@ -895,6 +896,7 @@ retry:
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
}
+ pipeselwakeup(wpipe);
wpipe->pipe_state |= PIPE_WANTW;
pipeunlock(wpipe);
error = msleep(wpipe, PIPE_MTX(wpipe),
@@ -1080,6 +1082,8 @@ pipe_write(fp, uio, active_cred, flags, td)
wpipe->pipe_state &= ~PIPE_WANTR;
wakeup(wpipe);
}
+ pipeselwakeup(wpipe);
+ wpipe->pipe_state |= PIPE_WANTW;
pipeunlock(wpipe);
error = msleep(wpipe, PIPE_MTX(rpipe), PRIBIO | PCATCH,
"pipbww", 0);
OpenPOWER on IntegriCloud