Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion context/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ The implementations live under `scheduler/selector/`, selected with Cargo featur

`FileStat::file_stat` queries an open descriptor and returns an owned associated metadata type. `FileMetadata` defines portable optional accessors for type, size, and access/modification/creation times, allowing native-backed results and simple simulated records. Readiness/Tokio wrap `std::fs::Metadata`; io_uring retains Linux `statx` directly in the request allocation, with native fields exposed on the concrete type. Avoid eager field normalization and additional output allocations. Returning by value keeps the interface simple; copy elimination is an optimization rather than a contract. The file and output survive waiter destruction until backend access ends. Metadata does not change the cursor or order concurrent modifications, and path-based lookup remains separate.

File operation traits share `FileOperation::File`; `FileStat` declares `Metadata`. `FileScheduler` is an automatically implemented aggregate of the core file capabilities, while `FileAllocate` and `FileAdvice` remain optional and depend only on `FileOperation`. Use narrow bounds for generic consumers and import individual operation traits for concrete method calls. The corresponding `SocketOperation` split is agreed follow-up work; `SocketScheduler` still declares its operations directly.
File operation traits share `FileOperation::File`; `FileStat` declares `Metadata`. `FileScheduler` is an automatically implemented aggregate of the core file capabilities, while `FileAllocate` and `FileAdvice` remain optional and depend only on `FileOperation`. Use narrow bounds for generic consumers and import individual operation traits for concrete method calls. Socket operation traits share `SocketOperation::Socket`, and `SocketScheduler` is their automatic core aggregate. `SocketMessages` aggregates `SocketSendMsg`/`SocketRecvMsg`, and `SocketOptions<O>` aggregates `SocketGetOption<O>`/`SocketSetOption<O>`. Each individual extension and `SocketRegistration` depend only on `SocketOperation`; consumers explicitly require any additional setup, transfer, or cleanup operations. Import operation traits for concrete method calls and use `<S as SocketOperation>::Socket` for qualified resource paths.

Spell out address names in the scheduler interface: `SocketAddress` re-exports `std::net::SocketAddr` unchanged, while `SocketLocalAddress::socket_local_address` and `SocketPeerAddress::socket_peer_address` distinguish the two endpoints. Public socket address parameters, message metadata, and resolver candidates use the re-export without introducing wrappers or conversion costs.

The Linux `io-uring` feature selects a dedicated ring for socket/file reads and writes, scatter/gather message sends/receives, and `file_sync`, plus descriptor-based `file_stat` using required `Statx` support. `file_truncate` uses the ring when its opcode is available, with a blocking-file fallback on older kernels. Optional `FileAllocate` adds Linux range reservation with `AllocationMode::Extend` or `KeepSize`, using a probed `Fallocate` request or the blocking syscall fallback. Other platforms currently omit that capability. Synchronization, allocation, and native truncation retain the file without a payload buffer and use the same original-completion retirement contract as transfers. Connect, accept, explicit readiness waits and sleep still use async-io. Initialization probes required opcodes and reliable completion overflow; it returns an error if unavailable rather than silently changing implementation. Shutdown cancels and drains original completions. Operation identifiers are never reused, and cancellation completions cannot release original buffers. Unexpected selector failure retains resources whose kernel lifetime cannot be established and panics their waiting operations. Normal cancellation does not retain completed resources.

Expand Down
2 changes: 1 addition & 1 deletion context/gaps.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The executor does not expose a Barrier or require a group/owner argument. Librar

## 3. The I/O boundary is still narrow

`SocketScheduler` uses one associated resource type for unconnected, bound, listening, connected, and datagram sockets. It exposes `socket_open`, `socket_bind`, syscall-like `socket_listen`, `socket_connect`, `socket_accept`, address inspection, reads, writes, and readiness. The initial API supports IPv4/IPv6 and stream/datagram sockets with optional TCP/UDP protocol selection. OS-resource import is a separate `SocketRegistration` capability. Socket close/shutdown and their admission-only variants are implemented; typed option get/set supports address reuse, keepalive, and TCP no-delay; `SocketMessages` implements owned scatter/gather payloads, addresses, peeking, routing flags, and receive truncation; ancillary data and further options remain future work. `FileScheduler` opens associated resources and borrows them for seeking, truncation, synchronization, shared-cursor and positioned I/O. Explicit close/submission now consumes an exclusively owned handle, and optional `FileAllocate` supplies Linux allocation and `FileAdvice` supplies hints with completion/submission forms. `file_stat` returns owned associated metadata with native storage and portable accessors; path-based metadata remains future work. File/socket operations support cancellation and owned buffer views. `Clock` supplies monotonic time and cancellable absolute and relative waits.
`SocketOperation` supplies one associated resource type for unconnected, bound, listening, connected, and datagram sockets. Individual operation traits, aggregated by `SocketScheduler`, expose `socket_open`, `socket_bind`, syscall-like `socket_listen`, `socket_connect`, `socket_accept`, address inspection, reads, writes, and readiness. The initial API supports IPv4/IPv6 and stream/datagram sockets with optional TCP/UDP protocol selection. OS-resource import is a separate `SocketRegistration` capability. Socket close/shutdown and their admission-only variants are implemented; typed option get/set supports address reuse, keepalive, and TCP no-delay; `SocketMessages` implements owned scatter/gather payloads, addresses, peeking, routing flags, and receive truncation; ancillary data and further options remain future work. `FileScheduler` opens associated resources and borrows them for seeking, truncation, synchronization, shared-cursor and positioned I/O. Explicit close/submission now consumes an exclusively owned handle, and optional `FileAllocate` supplies Linux allocation and `FileAdvice` supplies hints with completion/submission forms. `file_stat` returns owned associated metadata with native storage and portable accessors; path-based metadata remains future work. File/socket operations support cancellation and owned buffer views. `Clock` supplies monotonic time and cancellable absolute and relative waits.

`Blocking` now adds bounded asynchronous admission for owned synchronous closures, implemented through dedicated native and Tokio pools. `AddressResolution` uses the same bounded pools for system hostname lookup and returns owned address/type/protocol candidates with numeric or named services and native resolver hints; the simulator uses an explicit table. Started system lookups finish independently of cancellation. Existing file fallbacks still use backend pools. Ancillary data, further socket options, randomness, and processes remain outside the portable boundary. Deadline policies can now compose `Clock` and cancellation; higher-level timeout helpers remain separate. Ordinary synchronization uses futures and wakers above scheduler primitives. Expand capabilities as real consumers need them, keeping the application's implementation choice explicit. A broader boundary would also allow more operating-system behavior to be substituted in deterministic tests.

Expand Down
6 changes: 3 additions & 3 deletions context/implementation.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ This guide describes the current implementation and its boundaries. Read [the de
## I/O and runtime boundaries

- `scheduler.rs` re-exports SocketScheduler, FileScheduler, Interest and Clock from `scheduler/socket_scheduler.rs`, `file_scheduler.rs`, `interest.rs` and `clock.rs`. Operations return concrete Send futures; portable consumers receive the required capabilities.
- File operation traits share `FileOperation::File`; `FileStat` declares `Metadata`. `FileScheduler` is an automatically implemented aggregate of the core file capabilities, while `FileAllocate` and `FileAdvice` remain optional and depend only on `FileOperation`. Use narrow bounds for generic consumers and import individual operation traits for concrete method calls. The corresponding `SocketOperation` split is agreed follow-up work; `SocketScheduler` still declares its operations directly.
- File operation traits share `FileOperation::File`; `FileStat` declares `Metadata`. `FileScheduler` is an automatically implemented aggregate of the core file capabilities, while `FileAllocate` and `FileAdvice` remain optional and depend only on `FileOperation`. Use narrow bounds for generic consumers and import individual operation traits for concrete method calls. Socket operation traits share `SocketOperation::Socket`, and `SocketScheduler` is their automatic core aggregate. `SocketMessages` aggregates `SocketSendMsg`/`SocketRecvMsg`, and `SocketOptions<O>` aggregates `SocketGetOption<O>`/`SocketSetOption<O>`. Each individual extension and `SocketRegistration` depend only on `SocketOperation`; consumers explicitly require any additional setup, transfer, or cleanup operations. Import operation traits for concrete method calls and use `<S as SocketOperation>::Socket` for qualified resource paths.
- `FileOperation` declares an associated resource and `FileOpen` opens it with `FileOptions`; native/Tokio choose `Arc<std::fs::File>` internally. `SocketScheduler` creates IP socket descriptors with explicit bind/listen/connect and address inspection; standard-library resource import belongs to `SocketRegistration`. Blocking truncation, synchronization, shared-cursor, and positioned file helpers live in `scheduler/file_io.rs`. `file_seek` accepts `std::io::SeekFrom` and returns the resulting offset through a cancellable blocking fallback on all current native backends and the Tokio runtime pool; await it and other cursor operations in order. `file_read`/`file_write` advance the OS cursor with no extra per-file state or locking; io\_uring represents current-position requests with `None` internally and encodes them as offset `-1`. Await cursor operations sequentially when ordering matters, and retain buffers through terminal completion as for positioned I/O.
- `FileAllocate: FileOperation` optionally reserves space with `AllocationMode::Extend`/`KeepSize`. Native readiness and Tokio implement it on Linux using `fallocate64` on their file pools; io\_uring probes optional `Fallocate` and falls back when absent. Other targets currently omit the implementation. Positive length and a range end within `i64` are required; data and cursor are preserved, and filesystem support errors remain runtime results. No resize/zero-write emulation, unsharing, or durability promise. The simulator reserves vector capacity within its 1 MiB bound.
- `FileTruncate::file_truncate` changes the logical length with zero-filled extension, requiring write access and preserving the cursor. Lengths must fit in `i64`. Readiness and Tokio use `set_len` on their file pools; io\_uring probes optional `Ftruncate` support and falls back to the blocking implementation when absent. Buffer-free ring requests share resource retention and cancellation with sync. Await related operations sequentially; truncation provides neither space reservation nor durability. The simulator uses its 1 MiB bound.
Expand Down Expand Up @@ -114,15 +114,15 @@ Coverage measures source regions for native and Tokio schedulers on each support

## Typed socket options

- `SocketOption` describes an identifier's associated `Value`; `SocketOptions<O>: SocketScheduler` adds lazy cancellable `socket_get_option` and `socket_set_option`. Consumers require each supported option through trait bounds. The core `SocketScheduler` trait is unchanged.
- `SocketOption` describes an identifier's associated `Value`; `SocketGetOption<O>` and `SocketSetOption<O>`, aggregated as `SocketOptions<O>`, add lazy cancellable `socket_get_option` and `socket_set_option`. Consumers require each supported option through trait bounds. The core `SocketScheduler` trait is unchanged.
- `SocketReuseAddress`, `SocketKeepalive`, and `TcpNoDelay` use boolean values and preserve their OS meanings. Keepalive timing, additional options, and read-only/write-only controls remain separate extensions. Invalid resource protocols or states return OS errors even when the capability exists.
- Native mappings live privately in `scheduler/native_socket_option.rs`, using socket2's typed accessors. Readiness and Tokio execute them directly during a poll; io_uring delegates to readiness with its open check. Scheduler handles preserve shutdown and Tokio runtime validation. There is no readiness wait, pool dispatch, raw public ABI, or per-socket locking for these controls.
- Cancellation before execution prevents the syscall. Once executed, its result wins cancellation; an unpolled setter has no effect. Await configuration before dependent operations. Address reuse and accepted-socket inheritance vary by OS; configure accepted resources explicitly.
- Shared option tests run against native/Tokio schedulers and handles, standalone selectors, and the simulator. The simulator stores values independently of its stream state but does not model network timing, probe policy, address sharing, or inheritance. `examples/socket_options.rs` demonstrates generic listener configuration before binding.

## Message/address I/O

- `SocketMessages: SocketScheduler` adds `socket_sendmsg` and `socket_recvmsg`. `SocketMessage<B>` owns scatter/gather buffers and an optional destination; receive metadata returns copied bytes, sender address when available, and payload/control truncation. Buffer owners return on success, error, or cancellation, and initialized lengths remain unchanged. No `Sync` bound is added to `IoBuf`.
- `SocketSendMsg` and `SocketRecvMsg`, aggregated as `SocketMessages`, add `socket_sendmsg` and `socket_recvmsg`. `SocketMessage<B>` owns scatter/gather buffers and an optional destination; receive metadata returns copied bytes, sender address when available, and payload/control truncation. Buffer owners return on success, error, or cancellation, and initialized lengths remain unchanged. No `Sync` bound is added to `IoBuf`.
- `scheduler/message_io.rs` owns native metadata and validates representable lengths. Readiness/Tokio execute nonblocking syscalls; Windows uses vectored Winsock payload/address calls and normalizes message-too-large to truncation. Zero-capacity receives preserve OS differences; use nonempty storage for portable empty-message reception. `peek` and `dont_route` are the initial portable input flags.
- `selector/io_uring/message.rs` submits native message opcodes through the existing completion/cancellation machinery. Stable payload, header, address, and vector allocations survive until the original terminal CQE. Descriptor retention ends before completion notification. Close still requires completion of outstanding operations.
- Ancillary data is not supported by this capability. Unix reports control truncation; the Windows fallback cannot observe control metadata. Do not silently extend that fallback to ancillary-capable operations. The stream-only simulator has no `SocketMessages` implementation; shared message contracts run against the native backends and Tokio.
Expand Down
Loading
Loading