refactor(fspy): simplify shm_io to a plain frame arena - #578
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
b03e50b to
9485184
Compare
fspy benchmarklinuxmacoswindows |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b03e50b979
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let serialized_size = | ||
| usize::try_from(T::serialized_size(value)?).expect("serialized size exceeds usize"); | ||
| let Some(size) = NonZeroUsize::new(serialized_size) else { | ||
| return Err(WriteEncodedError::ZeroSizedFrame); |
There was a problem hiding this comment.
Check the closed gate before sizing encoded values
When write_encoded is called after the receiver has closed with a zero-sized value such as () or a schema whose size calculation fails, these early returns produce ZeroSizedFrame or Encode instead of Claim(Closed). The previous implementation entered the gate before calculating the serialized size, and the documented post-close contract requires writes to be reported as Claim(Closed) so callers can silently discard them; perform the gate check first and hold its guard through serialization.
Useful? React with 👍 / 👎.
9485184 to
a815712
Compare
2788743 to
e910409
Compare
98eff10 to
4deba7a
Compare
The gated API reads shared memory only when the gate is closed and nothing was in flight, which proves every claimed frame was fully written and published. The three-state frame header (`0` / `+size` / `-size`), the atomic header stores and the release fences existed so a reader could tolerate crashed or in-flight writers — states that are unreachable through the gate. Delete them. A frame is now `| size: u32 | content | padding |`, written once at claim time with a plain store, and the arena keeps exactly one atomic: its end offset. Crash exclusion lives entirely in the gate, where a leaked count fails closed — the run is not cached — instead of being parsed around. The arena also stops being a surface of its own and becomes an internal of the gated module. No public API change: `GatedShmWriter`, `GatedShmReceiver`, `GatedShmReader`, `FrameMut`, `ClaimError` and `StillWriting` keep their signatures, so the channel layer, the fspy crate and both preload clients are untouched. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4deba7a to
d5fee65
Compare

Motivation
The gated API reads shared memory only when the gate is closed and nothing was in flight, which proves every claimed frame was fully written and published — the gate guard is released only after the frame drops. The three-state frame header (
0/+size/-size), the atomic header stores and the release fences inshm_ioexisted so a reader could tolerate crashed or in-flight writers: states that are unreachable through the gated API.This deletes them. The arena keeps exactly one atomic, its end-offset word; a frame becomes
| size: u32 | content | padding |, written once at claim time with a plain store, because the claim already made the range exclusive and publication is the gate release rather than the header store. Crash exclusion lives entirely in the gate, where a leaked count fails closed — the run is not cached — instead of being parsed around at read time. The arena also stops being a surface of its own and becomes an internal of the gated module.No public API change:
GatedShmWriter,GatedShmReceiver,GatedShmReader,FrameMut,ClaimErrorandStillWritingkeep their signatures, so the channel layer, the fspy crate and both preload clients are untouched.🤖 Generated with Claude Code