summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/pipe.c19
-rw-r--r--src/kernel/proc.c3
-rw-r--r--src/kernel/proc.h1
3 files changed, 16 insertions, 7 deletions
diff --git a/src/kernel/pipe.c b/src/kernel/pipe.c
index 34cb263..edd1388 100644
--- a/src/kernel/pipe.c
+++ b/src/kernel/pipe.c
@@ -9,16 +9,19 @@ bool pipe_joinqueue(struct handle *h, bool wants_write,
assert(h && h->type == HANDLE_PIPE);
if (wants_write == h->pipe.write_end) return false;
if (!h->pipe.sister) return false;
- if (h->pipe.queued) {
- assert(h->pipe.queued->state == PS_WAITS4PIPE);
- panic_unimplemented();
+
+ struct process **slot = &h->pipe.queued;
+ while (*slot) {
+ assert((*slot)->state == PS_WAITS4PIPE);
+ slot = &((*slot)->waits4pipe.next);
}
process_transition(proc, PS_WAITS4PIPE);
- h->pipe.queued = proc;
+ *slot = proc;
proc->waits4pipe.pipe = h;
proc->waits4pipe.buf = pbuf;
proc->waits4pipe.len = pbuflen;
+ proc->waits4pipe.next = NULL;
return true;
}
@@ -46,19 +49,21 @@ void pipe_trytransfer(struct handle *h) {
{
panic_unimplemented();
}
+ h->pipe.queued = h->pipe.queued->waits4pipe.next;
+ h->pipe.sister->pipe.queued = h->pipe.sister->pipe.queued->waits4pipe.next;
process_transition(rdr, PS_RUNNING);
process_transition(wtr, PS_RUNNING);
- h->pipe.queued = NULL;
- h->pipe.sister->pipe.queued = NULL;
regs_savereturn(&rdr->regs, len);
regs_savereturn(&wtr->regs, len);
}
void pipe_invalidate_end(struct handle *h) {
struct process *p = h->pipe.queued;
- if (p) {
+ while (p) {
+ assert(p->state == PS_WAITS4PIPE);
process_transition(p, PS_RUNNING);
regs_savereturn(&p->regs, -1);
+ p = p->waits4pipe.next;
}
h->pipe.queued = NULL;
}
diff --git a/src/kernel/proc.c b/src/kernel/proc.c
index c69cb14..86170aa 100644
--- a/src/kernel/proc.c
+++ b/src/kernel/proc.c
@@ -116,6 +116,9 @@ void process_kill(struct process *p, int ret) {
if (p->state == PS_WAITS4FS)
p->waits4fs.req->caller = NULL;
+ if (p->state == PS_WAITS4PIPE)
+ panic_unimplemented();
+
for (handle_t h = 0; h < HANDLE_MAX; h++)
handle_close(p->handles[h]);
diff --git a/src/kernel/proc.h b/src/kernel/proc.h
index 20585bc..c400f7d 100644
--- a/src/kernel/proc.h
+++ b/src/kernel/proc.h
@@ -47,6 +47,7 @@ struct process {
struct handle *pipe;
char __user *buf;
size_t len;
+ struct process *next;
} waits4pipe;
};
struct vfs_request *handled_req;