summaryrefslogtreecommitdiffstats
path: root/sys/kern/sys_pipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/sys_pipe.c')
-rw-r--r--sys/kern/sys_pipe.c38
1 files changed, 24 insertions, 14 deletions
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 0f2d2de..2d26850 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -40,7 +40,7 @@
* process.
*
* If the sending process receives a signal, it is possible that it will
- * go away, and certainly it's address space can change, because control
+ * go away, and certainly its address space can change, because control
* is returned back to the user-mode side. In that case, the pipe code
* arranges to copy the buffer supplied by the user process, to a pageable
* kernel buffer, and the receiving process will grab the data from the
@@ -49,7 +49,7 @@
*
* The constant PIPE_MINDIRECT is chosen to make sure that buffering will
* happen for small transfers so that the system will not spend all of
- * it's time context switching. PIPE_SIZE is constrained by the
+ * its time context switching. PIPE_SIZE is constrained by the
* amount of kernel virtual memory.
*/
@@ -223,6 +223,7 @@ static void
pipeinit(cpipe)
struct pipe *cpipe;
{
+ int s;
cpipe->pipe_buffer.in = 0;
cpipe->pipe_buffer.out = 0;
@@ -234,9 +235,11 @@ pipeinit(cpipe)
cpipe->pipe_state = 0;
cpipe->pipe_peer = NULL;
cpipe->pipe_busy = 0;
+ s = splhigh();
cpipe->pipe_ctime = time;
cpipe->pipe_atime = time;
cpipe->pipe_mtime = time;
+ splx(s);
bzero(&cpipe->pipe_sel, sizeof cpipe->pipe_sel);
/*
@@ -340,7 +343,6 @@ pipe_read(fp, uio, cred)
rpipe->pipe_buffer.cnt -= size;
nread += size;
- rpipe->pipe_atime = time;
/*
* Direct copy, bypassing a kernel buffer.
*/
@@ -357,7 +359,6 @@ pipe_read(fp, uio, cred)
if (error)
break;
nread += size;
- rpipe->pipe_atime = time;
rpipe->pipe_map.pos += size;
rpipe->pipe_map.cnt -= size;
if (rpipe->pipe_map.cnt == 0) {
@@ -387,7 +388,7 @@ pipe_read(fp, uio, cred)
/*
* If there is no more to read in the pipe, reset
- * it's pointers to the beginning. This improves
+ * its pointers to the beginning. This improves
* cache hit stats.
*/
@@ -407,6 +408,12 @@ pipe_read(fp, uio, cred)
}
}
+ if (error == 0) {
+ int s = splhigh();
+ rpipe->pipe_atime = time;
+ splx(s);
+ }
+
--rpipe->pipe_busy;
if ((rpipe->pipe_busy == 0) && (rpipe->pipe_state & PIPE_WANT)) {
rpipe->pipe_state &= ~(PIPE_WANT|PIPE_WANTW);
@@ -414,7 +421,7 @@ pipe_read(fp, uio, cred)
} else if (rpipe->pipe_buffer.cnt < MINPIPESIZE) {
/*
* If there is no more to read in the pipe, reset
- * it's pointers to the beginning. This improves
+ * its pointers to the beginning. This improves
* cache hit stats.
*/
if ((error == 0) && (error = pipelock(rpipe,1)) == 0) {
@@ -645,6 +652,7 @@ pipewrite(wpipe, uio, nbio)
int nbio;
{
int error = 0;
+ int orig_resid;
/*
* detect loss of pipe read side, issue SIGPIPE if lost.
@@ -663,6 +671,7 @@ pipewrite(wpipe, uio, nbio)
}
++wpipe->pipe_busy;
+ orig_resid = uio->uio_resid;
while (uio->uio_resid) {
int space;
/*
@@ -693,13 +702,14 @@ pipewrite(wpipe, uio, nbio)
}
space = wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt;
+ if ((space < uio->uio_resid) && (orig_resid <= PIPE_BUF))
+ space = 0;
/*
* We must afford contiguous writes on buffers of size
* PIPE_BUF or less.
*/
- if ((space > 0) &&
- ((uio->uio_resid > PIPE_BUF) || (uio->uio_resid <= space))) {
+ if (space > 0) {
int size = wpipe->pipe_buffer.size - wpipe->pipe_buffer.in;
if (size > space)
size = space;
@@ -726,7 +736,6 @@ pipewrite(wpipe, uio, nbio)
wpipe->pipe_buffer.in = 0;
wpipe->pipe_buffer.cnt += size;
- wpipe->pipe_mtime = time;
} else {
/*
* If the "read-side" has been blocked, wake it up now.
@@ -780,6 +789,12 @@ pipewrite(wpipe, uio, nbio)
(uio->uio_resid == 0) &&
(error == EPIPE))
error = 0;
+
+ if (error = 0) {
+ int s = splhigh();
+ wpipe->pipe_mtime = time;
+ splx(s);
+ }
if (wpipe->pipe_state & PIPE_SEL) {
wpipe->pipe_state &= ~PIPE_SEL;
@@ -855,7 +870,6 @@ pipe_select(fp, which, p)
{
register struct pipe *rpipe = (struct pipe *)fp->f_data;
struct pipe *wpipe;
- register int s = splnet();
wpipe = rpipe->pipe_peer;
switch (which) {
@@ -863,7 +877,6 @@ pipe_select(fp, which, p)
case FREAD:
if (rpipe->pipe_buffer.cnt > 0 ||
(rpipe->pipe_state & PIPE_EOF)) {
- splx(s);
return (1);
}
selrecord(p, &rpipe->pipe_sel);
@@ -874,7 +887,6 @@ pipe_select(fp, which, p)
if ((wpipe == NULL) ||
(wpipe->pipe_state & PIPE_EOF) ||
((wpipe->pipe_buffer.size - wpipe->pipe_buffer.cnt) >= PIPE_BUF)) {
- splx(s);
return (1);
}
selrecord(p, &wpipe->pipe_sel);
@@ -885,7 +897,6 @@ pipe_select(fp, which, p)
if ((rpipe->pipe_state & PIPE_EOF) ||
(wpipe == NULL) ||
(wpipe->pipe_state & PIPE_EOF)) {
- splx(s);
return (1);
}
@@ -893,7 +904,6 @@ pipe_select(fp, which, p)
rpipe->pipe_state |= PIPE_SEL;
break;
}
- splx(s);
return (0);
}
OpenPOWER on IntegriCloud