Skip to content

Conversation

lalinsky
Copy link

@lalinsky lalinsky commented Oct 3, 2025

I wanted to add vectored I/O with minimal impact. I decided to only support 2 vectors, e.g. for reading two ends of a ring buffer. Vectors are stored as either iovec or WSABUF. This keeps ReadBuf/WriteBuf at the same size as before.

This commit adds full vectored I/O (scatter-gather) support to libxev,
implementing the infrastructure from the ground up across all 5 backends.

Core Infrastructure:
- Add .vectors union fields to ReadBuffer/WriteBuffer in all backends
- Implement vectored syscalls: readv/writev (Unix), WSASend/WSARecv (Windows)
- Update all file operations (.read, .write, .send, .recv, .pread, .pwrite)
- Add comprehensive switch case handling for vectored operations
- Platform-specific optimizations for io_uring, epoll, kqueue, iocp, wasi_poll

Backend Implementation Details:
- io_uring: prep_readv/prep_writev with SQE-based vectored operations
- epoll: posix.readv/writev/preadv/pwritev for all file operations
- kqueue: POSIX vectored syscalls with BSD-specific optimizations
- iocp: Windows WSABUF-based vectored I/O with WSASend/WSARecv
- wasi_poll: WebAssembly vectored operations via POSIX interface

User API:
- Add WriteBuffer.fromSlices() and ReadBuffer.fromSlices() convenience methods
- Automatic optimization: 0 slices → empty, 1 slice → .slice, 2+ → .vectors
- Platform abstraction: handles iovec (Unix) vs WSABUF (Windows) transparently
- Dynamic API support with backend delegation
- Type-safe, portable interface preventing common vectored I/O mistakes

Performance Benefits:
- Reduces syscall overhead for multi-buffer operations
- Enables scatter-gather I/O patterns (e.g., HTTP header + body in one call)
- Maintains zero-allocation design with embedded [2] buffer arrays
- Optimal fallback to single-buffer operations when appropriate

Example usage:
  const write_buf = xev.WriteBuffer.fromSlices(&.{ header, body });
  tcp.write(&loop, &completion, write_buf, void, null, callback);

This brings libxev's I/O capabilities to the same level as other high-performance
event loops while maintaining the library's cross-platform and zero-allocation
design principles.

Implement complete vectored I/O support for Windows IOCP backend

- Add .vectors case handling to all IOCP I/O operations (read, write, send, recv, etc.)
- Socket operations now support true vectored I/O using WSASend/WSARecv with WSABUF arrays
- File operations fall back to first buffer only (Windows ReadFile/WriteFile don't support vectored I/O)
- Fix compilation errors and ensure proper buffer count and pointer handling
- Tests pass successfully on Windows via Wine

Complete vectored I/O implementation for kqueue and wasi_poll backends

- Add .vectors case handling to all kqueue I/O operations (read, write, send, recv, etc.)
- Add .vectors case handling to all wasi_poll I/O operations  
- Fix machport buffer handling in kqueue backend
- Fix missing .vectors cases in file and stream watchers for kqueue
- Use native POSIX vectored syscalls (readv/writev/preadv/pwritev) for kqueue
- Use native WASI vectored I/O (sock_send/sock_recv with iovec arrays) for wasi_poll
- All backends now compile successfully with complete vectored I/O support

Now ALL 5 backends (io_uring, epoll, kqueue, iocp, wasi_poll) have proper vectored I/O implementation.

Use sendmsg/recvmsg for sockets, we need to define custom recvmsg wrapper as its not std at 0.15
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.

1 participant