Skip to content

Fix/pipe posix compliance#6299

Open
valydumitru01 wants to merge 9 commits intowasmerio:mainfrom
valydumitru01:fix/pipe-posix-compliance
Open

Fix/pipe posix compliance#6299
valydumitru01 wants to merge 9 commits intowasmerio:mainfrom
valydumitru01:fix/pipe-posix-compliance

Conversation

@valydumitru01
Copy link
Copy Markdown

Description

Rewrite pipe.rs with a POSIX-compliant, byte-bounded buffer backed by
Mutex<VecDeque<u8>>, replacing the previous mpsc channel.

Pipe fixes:

  • Enforce PIPE_CAPACITY (64 KB) at byte level, not message count
  • Enforce PIPE_BUF (4096) atomicity guarantee for writes
  • Correct WouldBlock vs BrokenPipe error mapping
  • Fix AsyncWrite which was silently using blocking tx.send()
  • Three-layer wake system: Condvar (blocking threads), Waker (async
    tasks), InterestHandler (external event loop)

fd_write.rs refactor (no behavioral changes outside of pipe paths):

  • Extract write_to_file, write_to_socket, write_to_pipe,
    write_to_event_notifications, write_to_buffer
  • Unify PipeTx and DuplexPipe arms via write_to_pipe(&mut dyn Write)
  • Introduce WriteOutcome struct and PipeWriteResult enum for type-safe
    broken-pipe signaling

Tests:

  • 27 unit tests covering the full pipe contract
  • E2E C tests: fork, vfork, SIGPIPE, EAGAIN, atomicity, dup2,
    drain-resume cycle, capacity bounds

Motivation

The pipe implementation was not POSIX-conformant and had multiple reported
bugs: #6279, #6148.

The fd_write refactor was done alongside for readability and to cleanly
support the new pipe error semantics (WouldBlock now surfaces as EAGAIN
through the existing map_io_err path).

Replace mpsc channel with Mutex<VecDeque<u8>> for correct byte-level
capacity tracking.

- Enforce PIPE_CAPACITY (64KB) at byte level, not message count
- Enforce PIPE_BUF (4096) atomicity guarantee for writes
- Correct WouldBlock vs BrokenPipe error mapping
- Fix AsyncWrite which was silently using blocking tx.send()
- Three-layer wake system: Condvar (blocking threads), Waker (async
  tasks), InterestHandler (external event loop)
- Add 27 unit tests covering full pipe contract
- Expand E2E C tests: fork, vfork, SIGPIPE, EAGAIN, atomicity, dup2,
  drain-resume cycle, capacity bounds

Refactor fd_write_internal into per-Kind helper functions to improve
readability and support the new pipe semantics:

- Extract write_to_file, write_to_socket, write_to_pipe,
  write_to_event_notifications, write_to_buffer
- Unify PipeTx and DuplexPipe arms via write_to_pipe(&mut dyn Write)
- Introduce WriteOutcome struct and PipeWriteResult enum for type-safe
  broken-pipe signaling
- No behavioral changes outside of pipe paths
Copilot AI review requested due to automatic review settings March 15, 2026 18:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the WASIX pipe implementation to better match POSIX semantics (bounded capacity, PIPE_BUF atomicity, corrected error mapping, and async wakeups), and refactors fd_write to route writes through per-kind helpers and handle pipe broken-pipe signaling more explicitly. It also extends the WASIX pipe E2E C test suite to cover nonblocking behavior, capacity bounds, dup2, and atomicity.

Changes:

  • Replace the previous pipe channel-based implementation with a byte-bounded VecDeque<u8> buffer and wake mechanisms for threads/async/interest handlers.
  • Refactor fd_write.rs into helper functions and introduce WriteOutcome / PipeWriteResult for clearer broken-pipe handling.
  • Add/extend WASIX pipe C tests for EAGAIN/EPIPE/SIGPIPE behavior, buffer bounds, and PIPE_BUF atomicity.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 16 comments.

File Description
lib/virtual-fs/src/pipe.rs New bounded pipe buffer implementation plus extensive Rust unit tests.
lib/wasix/src/syscalls/wasi/fd_write.rs Dispatcher refactor and updated pipe write/error signaling path.
tests/wasix/pipes/main.c Expanded E2E coverage for nonblocking pipes, bounds, dup2, and atomic writes.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@valydumitru01 valydumitru01 marked this pull request as draft March 15, 2026 18:56
Provided context to tx pipe inside inode_guard so we can store the
waker inside poll_write_ready.

Optimized read bytes for pipe buffer.

Fixed std::io::Write to be blocking.

Minor changes to tests.
@valydumitru01 valydumitru01 marked this pull request as ready for review March 15, 2026 21:30
The old mpsc channel auto-signaled EOF when senders dropped. The new
PipeBuffer does not, so readers blocked forever. Wrap close_write/
close_read in Arc-based drop guards to fire when the last clone drops.
@marxin marxin requested review from artemyarulin and theduke March 19, 2026 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants