From dad8b261ac7898f4d8cf537ad288ad6a1a74d124 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sat, 9 Jul 2022 15:24:58 +0200 Subject: syscalls/pipe: turn into a POSIX-style api with separate rw ends Without separate read/write ends you can't tell when there are no more writers left if you have multiple readers. Consider this piece of code: int fd = pipe(); fork(); // execution continues in 2 processes while (read(fd, &some_buf, sizeof somebuf) >= 0) { ... } Once both processes call `read()`, it's obvious that no writes are possible - all the processes that hold a reference to the pipe are currently stuck on a `read()` call, so the kernel could just make it return an error in both. But, what then? It's still possible to write to the pipe, and you can't know if the other process will do that. Thus, if you don't want to miss any output, you have to keep reading the pipe. Forever. Both processes end up stuck. Having separate read/write ends prevents that. --- src/kernel/handle.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/kernel/handle.h') diff --git a/src/kernel/handle.h b/src/kernel/handle.h index 4a5cab2..be8250b 100644 --- a/src/kernel/handle.h +++ b/src/kernel/handle.h @@ -18,7 +18,9 @@ struct handle { struct vfs_backend *backend; // HANDLE_FILE | HANDLE_FS_FRONT void __user *file_id; // only applicable to HANDLE_FILE struct { - struct process *reader, *writer; + struct process *queued; + bool write_end; + struct handle *sister; // the other end, not included in refcount } pipe; size_t refcount; -- cgit v1.2.3