Skip to content

util/ipc: Add AsyncChannelTransport, the kernel side of the service seam - #497

Merged
chrysh merged 1 commit into
OpenPRoT:ocp-global-demo-wipfrom
9elements:async-channel-transport
Sep 25, 2026
Merged

chrysh merged 1 commit into
OpenPRoT:ocp-global-demo-wipfrom
9elements:async-channel-transport

Conversation

@chrysh

@chrysh chrysh commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

The client seam from #464 made real: "every cross-process request goes through ServiceCall, and no process ever blocks on another."

AsyncTransaction lends the kernel 'static buffers for the life of a transaction, which a caller holding an ordinary &[u8] request cannot satisfy. AsyncChannelTransport owns that pair, copies each request in and each response out, and implements util_service::AsyncTransport. One type, every service: register as_raw() with a WaitGroup, start a request, poll once per wake.

Buffer sizes are the wiring's choice. A request longer than the send buffer, or a response longer than the caller's, is TooLarge rather than a truncated frame. Every failure path re-stows the buffers the transaction hands back, so the transport returns to idle and the next call is start.

One change to the layer below, in the first commit: AsyncTransaction::start now takes the request length. The kernel transmitted the whole send buffer, so a transport sized for its largest request also sent the slack behind a short one, and a transport that owns one &'static mut buffer cannot express the subslice any other way.

The QEMU test covers the round-trip, a request that does not fit, cancel then reuse, and the not-ready-then-ready sequence. That last one is the case #484 called out as untestable against a loopback, whose response is always ready on the first poll.

Not in here: the generic Loopback<D: Dispatch>, the blocking ChannelTransport (nothing on the #464 path blocks), and the typed PLDM client. Those follow, then the i2c and pldm migrations onto the shared seam.

Review the last commit only; below it are #482 and #485.

Progress toward 9elements#13.

AsyncTransaction lends the kernel 'static buffers, which a caller holding
an ordinary &[u8] request cannot satisfy. AsyncChannelTransport owns that
pair, copies each request in and each response out, and implements
util_service::AsyncTransport so every service shares one client seam
instead of writing its own.

Buffer sizes are the wiring's choice: a request longer than the send
buffer, or a response longer than the caller's, is TooLarge rather than a
truncated frame. Every failure path re-stows the buffers the transaction
hands back, so the transport is idle again and the next call is start.

The QEMU test covers the round-trip, a request that does not fit, cancel
then reuse, and the not-ready-then-ready sequence that a loopback cannot
produce because its response is always ready on the first poll.

Assisted-by: Claude Opus 5
@chrysh
chrysh force-pushed the async-channel-transport branch from f831a93 to 671064e Compare September 25, 2026 13:43
@chrysh
chrysh marked this pull request as ready for review September 25, 2026 13:44
@chrysh
chrysh merged commit 1b54ed3 into OpenPRoT:ocp-global-demo-wip Sep 25, 2026
1 check passed
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